2008-09-26 16 views
35

GWT'nin seri hale getiricisi sınırlı java.io.Serializable desteğine sahiptir, ancak güvenlik nedeniyle desteklediği türlerin beyaz listesi vardır. Bulduğum belgeler, örneğin this FAQ entry, serileştirmek istediğiniz her tür "dizileştirme ilkesi beyaz listeye dahil edilmelidir" ve listenin derleme zamanında üretildiğini, ancak derleyicinin neyin neden olduğuna karar verdiğini açıklamıyor. beyaz listede.GWT'nin Serileştirme İlkesi beyaz listesine nasıl bir yazı ekleyebilirim?

Oluşturulan liste, java.lang.String ve java.util.HashMap gibi standart kitaplığın bir parçası olan çeşitli türleri içerir. Serializable arabirimini uygulayan java.sql.Date seri hale getirmeye çalışırken bir hata alıyorum, ancak beyaz listede yok. Bu türü listeye nasıl ekleyebilirim?

cevap

12

servis arayüzünde dahil herhangi belirli türleri ve bunlar otomatik beyaz listeye alınan edilecektir başvuruda herhangi tipleri, yeter ki java.io.Serializable, örneğin uygularken Her ikisi de beyaz listeye dahil edilir.

denemek ve belirli türleri yerine java.lang.Object kullanmak eğer daha alır: derleyici Ne beyaz listeye bilmiyor

public Object getObjectForString(String str); 

çünkü. Bu durumda, nesneler servis arayüzünüzde herhangi bir yere referans verilmediyse, bunları IsSerializable arabirimiyle açıkça işaretlemeniz gerekir, aksi takdirde bunları RPC mekanizmasından geçirmenize izin vermezsiniz.

7

Beyaz liste, GWT derleyici tarafından oluşturulur ve IsSerializable işaretçi arabirimi tarafından belirlenen tüm girdileri içerir.

Listeye bir yazı eklemek için, yalnızca sınıfın IsSerializable arabirimini uyguladığından emin olmanız gerekir.

Seri hale getirmenin doğru çalışması için, sınıfın varsayılan bir arg kurucusu olması gerekir (gerekiyorsa kurucu özel olabilir). Ayrıca sınıf bir iç ise, statik olarak işaretlenmelidir.

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

ArrayList neden olacak ve:

+11

Eklenmelidir - sınıfın ayrıca bir genel varsayılan no-args kurucusuna sahip olması gerekir. Sadece IsSerializable arayüzünü bu olmadan uygulamak yeterli değildir. Bu hata ayıklama bir saat sonra zor yoldan buldum :) –

+2

@AdrianPetrescu Bu tamamen doğru değil. Hiçbir kod kurucusu özel olabilir, ancak yine de orada olmalıdır. Dahası, sınıfın kendisi özel olmamalı ve eğer bir iç sınıfsa, statik olmalıdır. Ve sınıf, son statik olmayan alanlara sahip olmayabilir. – FrankPl

29

Bir geçici çözüm var: serileştirme içine dahil edilmesini istediğiniz tüm türlerin üye alanlarıyla yeni bir Dummy sınıfı tanımlayın. Ardından RPC arabirimine bir yöntem ekleyin:

Dummy dummy(Dummy d); 

uygulama sadece şudur:

Dummy dummy(Dummy d) { return d; } 

Ve zaman uyumsuz arayüzü bu olacaktır:

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

GWT derleyici bu bulacaktır yukarı ve Dummy sınıfı bu türlere başvurduğundan, bunları beyaz listede içerecektir.

Örnek Dummy sınıfı: programlı beyaz listesi ulaşmak için En basit yolu, benzer bir sınıf oluşturmak için IMHO

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

:

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

sonra gelen .client paket ve referans içinde dahil RPC servisi (böylece derleyici tarafından analiz edilir).

Ben bazen daha genel hizmetler yaratabilmek için gerekenleri besbelli unparameterized haritaların kâğıdı ve etkinleştirmek için iyi bir yol bulamadı

...

+1

Ve bu tür bir RPC arabirimine eklemeden çalışır? –

+1

Hayır, bunu denemedim. – devconsole

1

istenen sonuç tüm war/<app>/gwt/*.gwt.rpc

silmek sağlamak için aynı soruyu sahip olacak ve tatminkar önceki cevaplar bulmak değil herkes için
0

... Ben in this message açıklandığı gibi modifiye Spring, kullanıyorum çünkü, GWTController ile GWT kullanıyorum

. Mesaj GrailsRemoteServiceServlet'in nasıl değiştirileceğini açıklar, ancak GWTController RPC.decodeRequest() ve RPC.encodeResponseForSuccess() yöntemlerini aynı şekilde çağırır. Beyaz liste gwt derleyici tarafından oluşturulan ve IsSerializable işaretleyici arayüzü tarafından belirlenmiş tüm girdileri içerir

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

:

Bu kullanıyorum GWTController son sürümüdür.

Listeye bir yazı eklemek için, yalnızca sınıfın IsSerializable arabirimini uyguladığından emin olmanız gerekir.

- Andrej

Bu muhtemelen en kolay çözümdür. Bunu hatırlamanız gereken tek şey, serileştirmek istediğiniz tüm sınıfların, üye alanları için "public, no-argument" kurucusu ve (gereksinimlere bağlı olarak) setter yöntemlerine sahip olmasıdır.

+0

Varsayılan kurucunun görünürlüğü önemli değil. Sadece herhangi bir görünürlüğün sıfır arg varsayılan kurucusuna ihtiyacınız var (özel bir irade bile) – thomaux

0

İstemci paketine koymanın veya kukla bir hizmet arayüzünde kullanmanın sistemin en iyi duruma getirilmiş gibi göründüğünden yeterli olmadığını buldum.

Hizmet arayüzünde zaten kullanılan türlerden türetilen ve istemci paketine yapıştıran bir sınıf oluşturmanın en kolay yolunu buldum. Başka bir şey gerekli değil.

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

bu sorun vardı ama benim Serializable nesnede bir kod satırına geri problemi izleme sona erdi:

: istisna yakalandığı önce başka hiçbir şikayetleri vardı
Logger.getLogger(this.getClass().getCanonicalName()).log(Level.INFO, "Foo"); 

@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); 
    } 
ve yığın izleme iş sonu:

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 = [email protected] 
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619) 
İlgili konular