Pergunta

apoio java.io.Serializable

serializer do GWT tem limitado, mas por razões de segurança não é uma lista branca de tipos que ele suporta. A documentação que eu encontrei, por exemplo esta entrada FAQ diz que todos os tipos que você quer serialize "deve ser incluída na política de serialização whitelist", e que a lista é gerada em tempo de compilação, mas não explica como o compilador decide o que vai na whitelist.

A lista gerada contém um número de tipos que fazem parte da biblioteca padrão, tais como java.lang.String e java.util.HashMap. Eu recebo um erro ao tentar java.sql.Date serialize, que implementa a interface Serializable, mas não está na lista branca. Como posso adicionar este tipo de lista?

Foi útil?

Solução

Qualquer tipos específicos que você incluir na sua interface de serviço e quaisquer tipos que eles referência será na lista de autorizações automaticamente, contanto que eles implementar java.io.Serializable, por exemplo:

public String getStringForDates(ArrayList<java.util.Date> dates);

resultará na ArrayList e Data sendo ambos incluídos na lista branca.

Ele fica mais complicado se você tentar usar java.lang.Object em vez de tipos específicos:

public Object getObjectForString(String str);

Porque o compilador não sabe o que whitelist. Nesse caso, se os objetos não são referenciados em qualquer lugar em sua interface de serviço, você tem que marcá-los explicitamente com a interface IsSerializable, caso contrário ele não vai deixar você passá-los através do mecanismo RPC.

Outras dicas

Há uma solução alternativa: definir uma nova classe Dummy com campos de membro de todos os tipos que você quer ser incluído na serialização. Em seguida, adicione um método para a sua interface RPC:

Dummy dummy(Dummy d);

A implementação é apenas isso:

Dummy dummy(Dummy d) { return d; }

E a interface assíncrona terá o seguinte:

void dummy(Dummy d, AsyncCallback< Dummy> callback);

O compilador GWT vai pegar isso, e porque as referências de classe Dummy esses tipos, ele irá incluí-los na lista branca.

Exemplo classe Dummy:

public class Dummy implements IsSerializable {
    private java.sql.Date d;
}

A lista branca é gerado pelo compilador GWT e contém todas as entradas que são designadas pelo interface de marcador IsSerializable.

Para adicionar um tipo de lista você só precisa ter certeza de que os instrumentos de classe da interface IsSerializable.

Além disso, para serialização para trabalho corretamente a classe deve ter um padrão nenhum construtor arg (construtor pode ser privado se necessário). Além disso, se a classe é uma interna deve ser marcado como estático.

IMHO a maneira mais simples para acesso whitelist programaticamente é criar uma classe semelhante a esta:

public class SerializableWhitelist implements IsSerializable {
    String[] dummy1;
    SomeOtherThingsIWishToSerialize dummy2;
}

Em seguida, incluí-lo no pacote .client e referência do serviço RPC (por isso, recebe analisados ??pelo compilador).

Eu não poderia encontrar uma maneira melhor para permitir tranfer de mapas unparameterized, que é, obviamente, o que às vezes você precisa, a fim de criar serviços mais genéricos ...

A lista branca é gerado pelo compilador GWT e contém todas as entradas que são designadas pelo interface de marcador IsSerializable.

Para adicionar um tipo de lista você só precisa ter certeza de que os instrumentos de classe da interface IsSerializable.

- Andrej

Esta é provavelmente a solução mais fácil. A única coisa a lembrar com isto é que todas as classes que você quer serialize deve ter "público, sem argumentos" construtor e (dependendo das necessidades) métodos setter para os campos de membro.

para garantir o resultado desejado excluir todos war/<app>/gwt/*.gwt.rpc

Para qualquer um que terá a mesma pergunta e não encontra respostas anteriores satisfatória ...

Eu estou usando GWT com GWTController, desde que eu estou usando Spring, que eu modificada conforme descrito nesta mensagem . A mensagem explica como modificar GrailsRemoteServiceServlet, mas GWTController chama RPC.decodeRequest () e RPC.encodeResponseForSuccess () da mesma forma.

Esta é a versão final do GWTController que estou usando:

/**
 * Used to instantiate GWT server in Spring context.
 *
 * Original version from <a href="http://docs.google.com/Doc?docid=dw2zgx2_25492p5qxfq&hl=en">this tutorial</a>.
 * 
 * ...fixed to work as explained <a href="http://blog.js-development.com/2009/09/gwt-meets-spring.html">in this tutorial</a>.
 * 
 * ...and then fixed to use StandardSerializationPolicy as explained in
 * <a href="http://markmail.org/message/k5j2vni6yzcokjsw">this message</a> to allow
 * using Serializable instead of IsSerializable in model.
 */
public class GWTController extends RemoteServiceServlet implements Controller, ServletContextAware {

 // Instance fields

 private RemoteService remoteService;

 private Class<? extends RemoteService> remoteServiceClass;

 private ServletContext servletContext;

 // Public methods

 /**
  * Call GWT's RemoteService doPost() method and return null.
  * 
  * @param request
  *            The current HTTP request
  * @param response
  *            The current HTTP response
  * @return A ModelAndView to render, or null if handled directly
  * @throws Exception
  *             In case of errors
  */
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
  doPost(request, response);
  return null; // response handled by GWT RPC over XmlHttpRequest
 }

 /**
  * Process the RPC request encoded into the payload string and return a string that encodes either the method return
  * or an exception thrown by it.
  * 
  * @param payload
  *            The RPC payload
  */
 public String processCall(String payload) throws SerializationException {
  try {
   RPCRequest rpcRequest = RPC.decodeRequest(payload, this.remoteServiceClass, this);

   // delegate work to the spring injected service
   return RPC.invokeAndEncodeResponse(this.remoteService, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy());
  } catch (IncompatibleRemoteServiceException e) {
   return RPC.encodeResponseForFailure(null, e);
  }
 }

 /**
  * Setter for Spring injection of the GWT RemoteService object.
  * 
  * @param RemoteService
  *            The GWT RemoteService implementation that will be delegated to by the {@code GWTController}.
  */
 public void setRemoteService(RemoteService remoteService) {
  this.remoteService = remoteService;
  this.remoteServiceClass = this.remoteService.getClass();
 }

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

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

Descobri que apenas colocá-lo no pacote do cliente ou usá-lo em uma interface de serviço fictício não foi suficiente como parecia o sistema otimizado de distância.

Eu achei mais fácil de criar uma classe que deriva de um dos tipos já utilizados na interface de serviço e colá-la no pacote de cliente. Nada mais necessário.

public class GWTSerializableTypes extends SomeTypeInServiceInterface implements IsSerializable {
    Long l;
    Double d;
    private GWTSerializableTypes() {}
}

Eu tive esse problema, mas acabou traçando as costas problema para uma linha de código no meu objeto Serializable:

Logger.getLogger(this.getClass().getCanonicalName()).log(Level.INFO, "Foo");

Não houve outras reclamações antes a exceção é pego em:

 @Override
  protected void serialize(Object instance, String typeSignature)
      throws SerializationException {
    assert (instance != null);

    Class<?> clazz = getClassForSerialization(instance);

    try {
      serializationPolicy.validateSerialize(clazz);
    } catch (SerializationException e) {
      throw new SerializationException(e.getMessage() + ": instance = " + instance);
    }
    serializeImpl(instance, clazz);
  }

E o fim do negócio do rastreamento de pilha é:

com.google.gwt.user.client.rpc.SerializationException: Type 'net.your.class' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = net.your.class@9c7edce
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top