tutorial - GWT: La respuesta no pudo ser deserializada
gwt tutorial (7)
Estoy usando GWT (2.4) con Spring integrado como en este artículo . Tengo un problema para obtener la lista de usuarios de la base de datos (Hibernate) y rellenar DataGrid con ella. Cuando llamo al método greetingService.allUsers()
, obtengo el error ( onFailure () ):
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: la respuesta no se pudo deserializar
Alguien ayuda con eso? Debajo algunos pedazos de código. El proyecto de trabajo completo está aquí .
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();
}
Usuario
@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;
}
La documentación para IncompatibleRemoteServiceException dice:
Esta excepción puede ser causada por los siguientes problemas:
- El {@ RemoteService} solicitado no se puede ubicar a través de {@link Class # forName (String)} en el servidor.
- La aplicación {@link RemoteService} solicitada no está implementada por la instancia {@link com.google.gwt.user.server.rpc.RemoteServiceServlet RemoteServiceServlet} que está configurada para procesar la solicitud.
- El método de servicio solicitado no está definido ni heredado por la interfaz {@ RemoteService} solicitada.
- Uno de los tipos utilizados en la invocación del método {@ RemoteService} ha agregado o eliminado campos.
- El código del cliente recibe un tipo del servidor que no puede
deserializar
En su caso es el último punto, usted tiene un tipo que no puede ser serializado y deserializado, esa es su clase de User
es uno de ellos. Debería tener un objeto de transferencia que implemente la interfaz com.google.gwt.user.client.rpc.IsSerializable
para transmitir el objeto User a través de la red. Para obtener más información, consulte: Compatibilidad con el lenguaje y las bibliotecas de Java . Los parámetros del método GWT RPC y los tipos de retorno se deben transmitir a través de una red entre aplicaciones cliente y servidor y, por lo tanto, deben ser serializables .
Intentaría un par de cosas.
- En Usuario, implemente solo com.google.gwt.user.client.rpc.IsSerializable y agregue un constructor en blanco . Recuerdo haber leído hace mucho tiempo que esto es necesario y resolvió un problema como este en uno de mis proyectos. Usuario público () {}
- Asegúrese de que su paquete esté definido en su archivo gwt.xml.
No está haciendo nada más complicado que no pueda ser serializado, así que debería estar bien con eso.
GwtRpcController
mi problema actualizando GwtRpcController
acuerdo con esto . Ahora la deserialización funciona bien sin usar ningún objeto de transferencia. Trabajando GwtRpcController
continuación.
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();
}
}
Todos, pasé mucho tiempo con esto, y tengo una solución diferente. Estaba usando una configuración muy simple y mis POJO no eran más que miembros y un CTOR.
Recreé un nuevo proyecto de GWT y agregué mis cosas al nuevo proyecto, añadiendo cada dependencia de POM.xml. Lo que encontré fue que el compilador de Maven estaba demasiado alto. Copié esto de otro proyecto sin pensarlo ... El lado del cliente de GWT es casi 1.5, tal vez 1.6 compatible ... por lo que estas configuraciones deben establecerse en 1.5, no en 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>
Tuve ese error al usar guava-gwt con el alcance "provisto". Para satisfacer las dependencias durante el tiempo de ejecución, agregué google-collections. El cliente de GWT no pudo deserializar esos.
Solución: elimine la dependencia google-collections y quédese con guayaba.
Para problemas con objetos serializables, puede probar esta lista de verificación:
- Verifique que la clase tenga un constructor predeterminado (sin argumentos)
- Verifique que la clase implementa Serializable o IsSerializable o implementa una interfaz que amplía Serializable o extiende una clase que implementa Serializable.
- Verifique que la clase se encuentre en un paquete de cliente * o ...
- Verifique, si la clase no está en el paquete del cliente. *, Que está compilada en su definición de módulo GWT xml. Por defecto está presente. Si su clase está en otro paquete, debe agregarla a la fuente. Por ejemplo, si su clase está bajo dominio. * Debe agregarla a xml como. ¡Tenga en cuenta que la clase no puede pertenecer al paquete del servidor! Más detalles en la página de GWT: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
- Si incluye la clase de otro proyecto GWT, debe agregar los heredados a la definición de su módulo xml. Por ejemplo, si su clase Foo está en el paquete com.dummy.domain, debe agregarla a la definición del módulo. Más detalles aquí: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
- Si incluye la clase de otro proyecto GWT publicado como jar, verifique que el contenedor contenga también el código fuente porque GWT recompila también el código fuente de Java para las clases pasadas al Cliente.
Fuente: http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/
Estoy trabajando en un equipo con un software maduro que un día dejó de funcionar debido a este error. El resto del equipo estaba bien. Intentamos varias cosas arreglarlo. Eventualmente, reinstalamos IntelliJ y eso lo solucionó.