GWT: ответ не может быть десериализован - PullRequest
6 голосов
/ 20 января 2012

Я использую GWT (2.4) с интегрированным Spring, как в этой статье . У меня проблема с получением списка пользователей из базы данных (Hibernate) и заполнение им DataGrid. Когда я вызываю greetingService.allUsers() метод, я получаю сообщение об ошибке ( onFailure () ):

com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: Ответ не может быть десериализован

Кто-нибудь помогает с этим? Ниже приведены некоторые фрагменты кода. Полный рабочий проект здесь .

  public void onModuleLoad() {
    // ...
    greetingService.allUsers(
        new AsyncCallback<List<User>>(){
            @Override
            public void onFailure(Throwable caught) {
                caught.printStackTrace();
            }
            @Override
            public void onSuccess(List<User> result) {
                GWT.log("SIZE: "+result.size());
                dataGrid.setRowData(result);
            }
        }
    );
    // ...
 }

GreetingServiceImpl

@Override
public List<User> allUsers() {
    return userDAO.findAll();
}

Пользователь

@Entity
@Table(name = "users")
public class User implements Serializable, IsSerializable {

    @Id
    private Long id;

    // only Strings and one Date
    private String login;
    private String password;
    private String firstname;
    private String lastname;
    private Date date;
}

Ответы [ 8 ]

6 голосов
/ 20 января 2012

Документация для IncompatibleRemoteServiceException гласит:

Это исключение может быть вызвано следующими проблемами:

  • Запрошенная {@link RemoteService} не может быть найдена через {@link Класс # forName (String)} на сервере.
  • Запрошенный {@link Интерфейс RemoteService} не реализован {@link com.google.gwt.user.server.rpc.RemoteServiceServlet RemoteServiceServlet} экземпляр, который настроен для обработки request.
  • Запрошенный метод обслуживания не определен или наследуется запрошенным интерфейсом {@link RemoteService}.
  • Один из типов, используемых в методе {@link RemoteService} В вызове добавлены или удалены поля.
  • Клиент код получает тип с сервера, который он не может
    десериализация.

В вашем случае это последний пункт, у вас есть тип, который нельзя сериализовать и десериализовать, это ваш класс User, один из них. У вас должен быть один объект передачи, который реализует интерфейс com.google.gwt.user.client.rpc.IsSerializable для передачи объекта пользователя по сети. Для получения дополнительной информации см .: Совместимость с языком Java и библиотеками . Параметры метода GWT RPC и типы возврата должны передаваться по сети между клиентскими и серверными приложениями, и поэтому они должны быть сериализуемыми .

2 голосов
/ 21 января 2012

Я бы попробовал пару вещей.

  • В пользовательской реализации просто com.google.gwt.user.client.rpc.IsSerializable и добавьте пустой конструктор .Я помню, как читал где-то давным-давно, что это необходимо, и это решило такую ​​проблему в одном из моих проектов.public User () {}
  • Убедитесь, что ваш пакет определен в вашем файле gwt.xml.

Вы не делаете ничего более сложного, что не может быть сериализовано, поэтому вам должно быть хорошо с этим.

1 голос
/ 23 января 2012

Я решил свою проблему, обновив GwtRpcController в соответствии с this .Теперь десериализация работает хорошо без использования какого-либо объекта переноса.Рабочая GwtRpcController ниже.

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class GwtRpcController extends RemoteServiceServlet implements
        Controller, ServletContextAware {

    private static final long serialVersionUID = 1L;

    private ServletContext servletContext;

    private RemoteService remoteService;

    private Class remoteServiceClass;

    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        super.doPost(request, response);
        return null;
    }

    @Override
    public String processCall(String payload) throws SerializationException {
        try {

            RPCRequest rpcRequest = RPC.decodeRequest(payload, this.remoteServiceClass, this);
            onAfterRequestDeserialized(rpcRequest);

            // delegate work to the spring injected service
            return RPC.invokeAndEncodeResponse(this.remoteService, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy());
        } catch (IncompatibleRemoteServiceException ex) {
            getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
            return RPC.encodeResponseForFailure(null, ex);
        }
    }

    @Override
    public ServletContext getServletContext() {
        return servletContext;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    public void setRemoteService(RemoteService remoteService) {
        this.remoteService = remoteService;
        this.remoteServiceClass = this.remoteService.getClass();
    }

}
0 голосов
/ 04 марта 2018

Иногда эта ошибка может быть связана с устаревшими / поврежденными файлами / кэшем на стороне клиента (в этом случае сообщение об ошибке на стороне сервера отсутствует).Я только что запустил «модуль перестройки» в IntelliJ, и все снова было в порядке.

0 голосов
/ 16 июня 2014

Я работаю в команде со зрелым программным обеспечением, которое однажды перестало работать для меня из-за этой ошибки. Остальная часть команды была в порядке. Мы попробовали любое количество вещей, чтобы исправить это. В конце концов, мы переустановили IntelliJ, и это исправило его.

0 голосов
/ 29 апреля 2014

Для проблем с сериализуемыми объектами, вы можете попробовать этот контрольный список:

  1. Убедитесь, что класс имеет конструктор по умолчанию (без аргументов)
  2. Убедитесь, что класс реализует Serializable илиIsSerializable или реализует Интерфейс, который расширяет Serializable или расширяет класс, который реализует Serializable
  3. Убедитесь, что класс находится в пакете client. * Или…
  4. Убедитесь, что класс отсутствует в клиенте.* пакет, который скомпилирован в определении вашего модуля GWT xml.По умолчанию присутствует.Если ваш класс находится в другом пакете, вы должны добавить его в исходный код.Например, если ваш класс находится в домене. * Вы должны добавить его в XML как.Имейте в виду, что класс не может принадлежать серверу!Подробнее на странице GWT: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
  5. Если вы включаете класс из другого проекта GWT, вам нужно добавить наследование в определение вашего модуля xml.Например, если ваш класс Foo находится в пакете com.dummy.domain, вы должны добавить его в определение модуля.Подробнее здесь: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
  6. Если вы включаете класс из другого проекта GWT, выпущенного как jar, убедитесь, что в jar также содержится исходный код, потому что GWT перекомпилирует также исходный код Java для классов, передаваемых клиенту.

Шрифт: http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/

0 голосов
/ 15 февраля 2014

У меня была эта ошибка при использовании guava-gwt с областью "предоставлено". Чтобы удовлетворить зависимости во время выполнения, я добавил google-collection. Клиент GWT не может десериализовать их.

Решение: удалите зависимости google-collection и придерживайтесь гуавы.

0 голосов
/ 02 апреля 2013

Все, провел много времени с этим, и у меня есть другое решение.Я использовал очень простую настройку, и мои POJO были не более чем членами и CTOR.

Я заново создал новый проект GWT и добавил свои вещи обратно в новый проект, добавив каждую зависимость POM.xml обратно вЯ обнаружил, что компилятор maven был установлен слишком высоко.Я скопировал это из другого проекта, не думая об этом ... Клиентская сторона GWT в значительной степени совместима только с 1,5, может быть, 1,6 ... поэтому эти настройки должны быть установлены на 1,5, а не на 1,7

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>2.3.2</version>
 <configuration>
  <source>1.7</source>                     <!-- change these to 1.5 -->
  <target>1.7</target>
 </configuration>
</plugin>
...