问题
I'm using GWT (2.4) with Spring integrated as in this article. I have problem with getting list of User from database (Hibernate) and populate DataGrid with it. When i call greetingService.allUsers()
method, I'm getting error (onFailure()):
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: The response could not be deserialized
Anybody helps with that? Below some pieces of code. Full working project is here.
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();
}
User
@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;
}
回答1:
Documentation for IncompatibleRemoteServiceException says:
This exception can be caused by the following problems:
- The requested {@link RemoteService} cannot be located via {@link Class#forName(String)} on the server.
- The requested {@link RemoteService} interface is not implemented by the {@link com.google.gwt.user.server.rpc.RemoteServiceServlet RemoteServiceServlet} instance which is configured to process the request.
- The requested service method is not defined or inherited by the requested {@link RemoteService} interface.
- One of the types used in the {@link RemoteService} method invocation has had fields added or removed.
- The client code receives a type from the server which it cannot
deserialize.
In your case is the last point, you have a type which cannot be serialized and deserialized, that's a your User
class is one of them. You should have one transfer object which implements com.google.gwt.user.client.rpc.IsSerializable
interface for transmitting the User object across the network. For further information see: Compatibility with the Java Language and Libraries. GWT RPC method parameters and return types must be transmitted across a network between client and server applications and therefore they must be serializable.
回答2:
I would try a couple of things.
- In User implement just com.google.gwt.user.client.rpc.IsSerializable and add a blank constructor. I remember reading somewhere a long time ago that this is needed and it solved a problem like this in one of my projects. public User() { }
- Make sure your package is defined in your gwt.xml file.
You are not doing anything more complicated that cannot be serialized so you should be fine with that.
回答3:
I solved my problem by updating GwtRpcController
according to this. Now deserialization works good without using any transfer object. Working GwtRpcController
below.
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();
}
}
回答4:
All, Spent alot of time with this, and I have a different solution. I was using a very simple setup and my POJOs were really nothing more that members and a CTOR.
I recreated a new GWT project and added my stuff back into the new project, adding each POM.xml dependency back in. What I found was the maven compiler was set too high. I had copied this in from another project not thinking about it... GWT client side is pretty much only 1.5, maybe 1.6 compatible... so these settings need to be set to 1.5, not 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>
回答5:
I had that error when using guava-gwt with scope "provided". In order to satisfy the dependencies during runtime, I added google-collections. GWT client couldn't deserialize those.
Solution: remove dependency google-collections, and stick with guava.
回答6:
To problems with serializable objects, you can try this check list:
- Verify that the class has a default constructor (without arguments)
- Verify that the class implements Serializable or IsSerializable or implements an Interface that extends Serializable or extends a class that implement Serializable
- Verify that the class is in a client.* package or …
- Verify, if the class is not in client.* package, that is compiled in your GWT xml module definition. By default is present. If your class is in another package you have to add it to source. For example if your class is under domain.* you should add it to xml as . Be aware that the class cannot belong to server package! More details on GWT page: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
- If you are including the class from another GWT project you have to add the inherits to your xml module definition. For example if your class Foo is in the package com.dummy.domain you have to add to the module definition. More details here: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
- If you are including the class from another GWT project released as a jar verify that the jar contains also the source code because GWT recompile also the Java source for the classes passed to the Client.
Font: http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/
回答7:
I am working in a team with mature software which one day stopped working for me due to this error. The rest of the team was fine. We tried any number of things to fix it. Eventually, we reinstalled IntelliJ and that fixed it.
回答8:
Sometimes this error can be due to outdated/corrupted client-side files/cache (There is no server side error message in this case). I just ran "rebuild module" in IntelliJ and it was fine again.
来源:https://stackoverflow.com/questions/8943147/gwt-the-response-could-not-be-deserialized