Frage

GWT Serializer hat begrenzte java.io.Serializable Unterstützung, aber aus Sicherheitsgründen gibt es eine weiße Liste von Typen unterstützt. Die Dokumentation die ich gefunden habe, zum Beispiel dieser FAQ-Eintrag sagt, dass alle Typen, die Sie „in der Serialisierung Politik weißen Liste enthalten sein muß“ serialisiert werden sollen, und dass die Liste bei der Kompilierung erzeugt wird, aber nicht erklärt, wie der Compiler, was auf der weißen Liste geht entscheidet.

Die erzeugte Liste enthält eine Reihe von Typen, die Teil der Standardbibliothek, wie java.lang.String und java.util.HashMap sind. Ich erhalte eine Fehlermeldung beim Versuch java.sql.Date serialisiert wird, die den Serializable-Schnittstelle implementiert, ist aber nicht auf der weißen Liste. Wie kann ich diese Art zu der Liste hinzufügen?

War es hilfreich?

Lösung

Alle spezifischen Typen, die Sie in Ihrem Service-Schnittstelle und alle Arten umfassen, die sie verweisen automatisch die weiße Liste gesetzt werden, solange sie implementieren java.io.Serializable, zum Beispiel:

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

Wird in Arraylist und Datum führen sowohl auf der weißen Liste enthalten sind.

Es wird schwieriger, wenn Sie versuchen, und verwenden java.lang.Object statt spezifische Typen:

public Object getObjectForString(String str);

Da der Compiler nicht weiß, was zu weißen Liste. In diesem Fall, wenn die Objekte nicht überall in Ihrem Service-Interface referenziert, müssen Sie sie explizit mit der IsSerializable Schnittstelle markieren, sonst wird es Sie sie durch den RPC-Mechanismus nicht passieren lassen.

Andere Tipps

Es gibt eine Lösung: eine neue Dummy Klasse mit Feldern aller Typen definieren, die Sie in der Serialisierung enthalten sein sollen. Dann fügen Sie eine Methode, um Ihre RPC-Schnittstelle:

Dummy dummy(Dummy d);

Die Implementierung ist einfach so:

Dummy dummy(Dummy d) { return d; }

Und die Asynchron-Schnittstelle wird dies:

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

Die GWT-Compiler werden diese abholen, und weil die Dummy Klasse dieser Typen verweist, es wird sie in der weißen Liste enthalten.

Beispiel Dummy Klasse:

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

Die Weiße Liste wird durch die GWT-Compiler erzeugt und enthält alle Einträge, die von der IsSerializable Markierungsschnittstelle bezeichnet werden.

Um einen Typen zur Liste hinzufügen Sie müssen nur sicherstellen, dass die Klasse den IsSerializable-Schnittstelle implementiert.

Zusätzlich zur Serialisierung arbeitet korrekt die Klasse eine Standard keinen arg Konstruktor haben muß (Konstruktor kann privat sein, wenn erforderlich). Auch wenn die Klasse ein inneres ist, muss es als statisch markiert werden.

IMHO die einfachste Art und Weise weiße Liste programmatisch zuzugreifen, ist eine Klasse ähnlich wie diese zu erstellen:

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

Dann schließt sie in der Paket- und .client Referenz von dem RPC-Dienst (so dass es durch den Compiler analysiert wird).

ich hätte keine bessere Art und Weise zu ermöglichen Tranfer von unparameterized Karten finden, was offensichtlich ist, was Sie manchmal brauchen, um mehr Basisdienste zu schaffen ...

  

Die Weiße Liste wird durch die GWT-Compiler erzeugt und enthält alle Einträge, die von der IsSerializable Markierungsschnittstelle bezeichnet werden.

     

Um einen Typen zur Liste hinzufügen Sie müssen nur sicherstellen, dass die Klasse den IsSerializable-Schnittstelle implementiert.

     

- Andrej

Dies ist wahrscheinlich die einfachste Lösung. Das einzige, was mit mir daran zu erinnern ist, dass alle Klassen, die Sie serialisieren mögen sollten „public, no-Argument“ haben Konstruktor und (je nach Bedarf) Setter-Methoden für die Mitglieder Felder aus.

, um das gewünschte Ergebnis löschen all war/<app>/gwt/*.gwt.rpc, um sicherzustellen,

Für jeden, der die gleiche Frage haben und nicht findet frühere Antworten zufriedenstellend ...

Ich verwende GWT mit GWTController, da ich Frühling bin mit, die ich wie beschrieben modifizierte in dieser Nachricht . Die Meldung wird erläutert, wie GrailsRemoteServiceServlet zu ändern, aber GWTController ruft RPC.decodeRequest () und RPC.encodeResponseForSuccess () in der gleichen Weise.

Dies ist die letzte Version von GWTController Ich verwende:

/**
 * 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;
 }
}

Ich fand, dass es nur in der Client-Paket setzen oder es in einer Dummy-Service-Schnittstelle war nicht ausreichend, da sie das System es weg optimiert zu sein schien.

Ich fand es am einfachsten, eine Klasse zu erstellen, die von einem des Typ bereits in der Service-Schnittstelle verwendet abgeleitet und es in dem Client-Paket kleben. Nichts anderes benötigt wird.

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

hatte ich dieses Problem, aber das Problem wieder in eine Zeile Code in meinem Serializable Objektnachführungsrahmen ende:

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

Es gab keine andere Beschwerden, bevor die Ausnahme in verfängt:

 @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);
  }

Und das Geschäft Ende des Stack-Trace ist:

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top