java - GWT序列化: polymorphism with generics

标签 java gwt generics serialization polymorphism

解决了serialization with JAXB的问题后,我在将 DTO 与 GWT(版本 2.5.1)一起使用时遇到问题:

@XmlRootElement
public class Performance<M extends IMeasurement> implements Serializable {

    @XmlElementWrapper(name = "measurementsPerformance")
    @XmlElements({
        @XmlElement(name = "measurement", type = MeasurementStringDouble.class),
        @XmlElement(name = "measurement", type = MeasurementStringInteger.class)})
    private List<M> measurement;   

    public List<M> getMeasurement() {
        if (measurement == null) {
            measurement = new ArrayList<M>();
        }
        return measurement;
    }

    public void setMeasurement(List<M> measurement) {
        this.measurement = measurement;
    }
}
public interface IMeasurement<D extends Serializable, V extends Number> extends Serializable {

    D getDate();    
    void setDate(D date);    
    V getValue();    
    void setValue(V value);
}
@XmlTransient
public abstract class MeasurementAbstract<D extends Serializable, V extends Number> implements IMeasurement<D, V>, Serializable {

    protected D date;
    protected V value;
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class MeasurementStringDouble extends MeasurementAbstract<String, Double> {

    @XmlElement
    @Override
    public String getDate() {
        return date;
    }

    @XmlElement
    @Override
    public Double getValue() {
        return value;
    }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class MeasurementStringInteger extends MeasurementAbstract<String, Integer> {

    @XmlElement
    @Override
    public String getDate() {
        return date;
    }

    @XmlElement
    @Override
    public Integer getValue() {
        return value;
    }
}

与服务器通信的RPC方法:

// Into my interface extends RemoteService 
Performance<MeasurementStringDouble> getPerformance();

// Into my async interface
void getPerformance(AsyncCallback<Performance<MeasurementStringDouble>> callback);

// Into my implementation extends RemoteServiceServlet and implements my interface
public Performance<MeasurementStringDouble> getPerformance() {
    Performance<MeasurementStringDouble> p = new Performance<MeasurementStringDouble>();

    List<MeasurementStringDouble> m = p.getMeasurement();
    m.add(new MeasurementStringDouble("Mar-12", 0.396));

    return p;
}

我有这个错误:

subtype Performance<M> is not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' or 'java.io.Serializable' nor does it have a custom field serializer (reached via Performance<MeasurementStringDouble>)

完整堆栈跟踪:

[DEBUG] Rebinding org.test.client.SMService
[DEBUG] Invoking generator com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator
[DEBUG] Generating client proxy for remote service interface 'org.test.client.SMService'
[ERROR] org.test.shared.Performance<M> is not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' or 'java.io.Serializable' nor does it have a custom field serializer (reached via org.test.shared.Performance<org.test.shared.MeasurementStringDouble>)
[ERROR] org.test.shared.Performance<M> has no available instantiable subtypes. (reached via org.test.shared.Performance<org.test.shared.MeasurementStringDouble>)
[ERROR] subtype org.test.shared.Performance<M> is not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' or 'java.io.Serializable' nor does it have a custom field serializer (reached via org.test.shared.Performance<org.test.shared.MeasurementStringDouble>)
[ERROR] Deferred binding failed for 'org.test.client.SMService'; expect subsequent failures
[ERROR] Unable to load module entry point class org.test.client.SMWebApp (see associated exception for details)
java.lang.RuntimeException: Deferred binding failed for 'org.test.client.SMService' (did you forget to inherit a required module?)  at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:53)     at com.google.gwt.core.shared.GWT.create(GWT.java:57)   at com.google.gwt.core.client.GWT.create(GWT.java:85)   at org.test.client.SMPerformance.<init>(SMPerformance.java:75)  at org.test.client.org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.org$test$client$SMPerformance_org$test$client$SMPerformance_methodInjection(org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.java:48)   at org.test.client.org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.get_Key$type$org$test$client$SMPerformance$_annotation$$none$$(org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.java:38)    at org.test.client.injector.org_test_client_injector_SMInjectorImpl.getWidgetPerformance(org_test_client_injector_SMInjectorImpl.java:26)   at org.test.client.SMWebApp.onModuleLoad(SMWebApp.java:45)  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)    at java.lang.reflect.Method.invoke(Method.java:597)     at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:406)    at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:526)   at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)     at java.lang.Thread.run(Thread.java:662) Caused by: com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)   at com.google.gwt.dev.shell.ModuleSpace.rebind(ModuleSpace.java:605)    at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:465)   at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:49)     at com.google.gwt.core.shared.GWT.create(GWT.java:57)   at com.google.gwt.core.client.GWT.create(GWT.java:85)   at org.test.client.SMPerformance.<init>(SMPerformance.java:75)  at org.test.client.org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.org$test$client$SMPerformance_org$test$client$SMPerformance_methodInjection(org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.java:48)   at org.test.client.org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.get_Key$type$org$test$client$SMPerformance$_annotation$$none$$(org_test_client_injector_SMInjector_SMInjectorGinjector_fragment.java:38)    at org.test.client.injector.org_test_client_injector_SMInjectorImpl.getWidgetPerformance(org_test_client_injector_SMInjectorImpl.java:26)   at org.test.client.SMWebApp.onModuleLoad(SMWebApp.java:45)  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)    at java.lang.reflect.Method.invoke(Method.java:597)     at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:406)    at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:526)   at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)     at java.lang.Thread.run(Thread.java:662)
[ERROR] Failed to load module 'smwebapp' from user agent 'Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0' at 127.0.0.1:50032

我在客户端使用 IMeasurement 对象没有问题。

最佳答案

您有用于“测量”字段的 getter 和 setter 吗? GWT 序列化两者都需要。另外,最好使用 ArrayList 而不是 LinkedList 作为实现。

关于java - GWT序列化: polymorphism with generics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17576359/

相关文章:

java - 循环从 0 到 100 的数字,并使用递归打印出每三个数字而不使用模函数

java - 使用 JaCoCo 和 spring-boot-maven-plugin 生成代码覆盖率

java - JScrollPane、JTextArea 和 JPanel 的问题

java - Spring 测试 : transaction not rolling back after test method executed

java - HTML 标签未反射(reflect)在 Gxt Grid 中

java - GWT 的工具提示

Java - 对多种类型使用泛型

java - 将 Eclipse/GWT 插件应用程序拆分为单独的项目

Java泛型方法

ios - 在类型化数组中存储符合泛型协议(protocol)的对象