在用 JAXB解决了序列化问题后,我在使用 GWT(版本 2.5.1)的 DTO 时遇到了问题:
@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 对象没有问题。