我有一个GWT内置的Web应用程序,它需要在客户端发送和接收序列化数据。 (我正在使用Webworkers,并且需要在主线程和Webworkers之间交换数据)
到目前为止,我正在创建序列化的对象(在此示例中,我只是发送字符串对象的ArrayList,但是我当然是在尝试发送可序列化的类对象的数组)
当序列化/反序列化过程全部发生在客户端时,似乎没有多少文档可以正确使用该序列化/反序列化过程。
但是我的writer函数的一般形式为:
public String streamResult(){
SerializationStreamFactory factory = GWT.create(streamFactory.class);
SerializationStreamWriter writer = factory.createStreamWriter();
ArrayList<String> strlst = new ArrayList<>();
strlst.add("First String");
strlst.add("Second String");
try {
writer.writeObject(strlst);
} catch (Exception e) {
printf("exception caught while serializing object");
}
return writer.toString();
}
这会正确创建一个表示ArrayList数据的字符串对象
"7|0|6||788C596190777F280A9EF3D57029FB2C|java.util.ArrayList/4159755760|java.lang.String/2004016611|First String|Second String|1|2|3|2|4|5|4|6|"
但是当我去对结果集进行反序列化时,我得到一个错误,该错误与尝试读取结果字符串中的整数有关。
public void unStreamResult(String str){
SerializationStreamFactory factory = GWT.create(streamFactory.class);
try {
SerializationStreamReader reader = factory.createStreamReader(str);
stringArray.addAll((ArrayList<String>) reader.readObject());
} catch (Exception e){
printf("exception caught while deseralizing object");
}
}
为我的SeralizationStreamFactory创建的streamFactory类定义为:
@RemoteServiceRelativePath("streamFactory")
public interface streamFactory extends RemoteService {
ArrayList getMessage(ArrayList message);
String getMessage(String message);
}
但是在反序列化过程中,我在某种字符串“”上得到了一个 NumberFormatException 。
错误:java.lang.NumberFormatException:对于输入字符串:“” 在NumberFormatException_0.createError(Insights-0.js:13972) 在NumberFormatException_0.initializeBackingError(Insights-0.js:13995) 在NumberFormatException_0.Throwable_0(Insights-0.js:13948) 在NumberFormatException_0.Exception_0(Insights-0.js:14012) 在NumberFormatException_0.RuntimeException_0(Insights-0.js:14022) 在NumberFormatException_0.IllegalArgumentException_0(Insights-0.js:46625) 在新的NumberFormatException_0(Insights-0.js:46861) 在__parseAndValidateInt(Insights-0.js:22987) 在$ prepareToRead(Insights-0.js:39707) 在$ unStreamResult(Insights-0.js:9415) 在onMessageImpl(Insights-0.js:46204) 在Worker.this $ static.onmessage(Insights-0.js:46198)
答案 0 :(得分:2)
现有的GWT-RPC协议是非对称的-一种消息格式用于从客户端到服务器,而另一种格式用于从服务器到客户端。在我使用RPC的所有工作中,我从来都不明白为什么会这样,只是因为这两种消息格式不兼容,所以使调试变得轻而易举,所以您一眼就能知道要寻找什么?
无论如何,这就是为什么它不起作用的原因-您的unStreamResult
期望使用另一种格式的消息,该消息应以//OK
或//EX
开头,然后跟一个JS数组。该数组将主要包含数字,但还将包含字符串数组。
在当前https://github.com/vertispan/gwt-rpc的GWT-RPC存储库更新草案中(如果该链接过时,请在此答案上留下消息,我将进行更新),我们将流读取器和写入器更改为完全对称。这样可以避免您和其他人所面临的困惑,并可以独立使用序列化格式,例如与Web Worker进行通信,或者可以将一些简单的序列化为Blob以在IndexedDb中使用,等等。此格式不是 版本,因此在更新应用程序后持久存储的数据可能不再起作用。
如果在我完成该项目之前必须先使用这种格式,请查看类似https://github.com/niloc132/webbit-gwt/blob/master/workers/src/main/java/com/colinalworth/gwt/worker/client/impl/StreamReader.java(和同一包中的StreamWriter.java)的内容-这些只是AbstractSerializationStreamReader
和{的子类型{1}},但要仔细写成避免客户与读者之间的差异。这些被编写为使用ByteBuffers(它们本身包装JS TypedArrays以获得更好的性能)。 gwt-rpc项目中有一个针对字符串和ByteBuffer的“现代化”版本,但是它们可能与旧的RPC不完全兼容。使用它们还会带来额外的工作:您必须停止使用AbstractSerializationStreamWriter
等为您构建读取器和写入器,然后必须从RemoteServiceProxy子类(也许是JSNI?)中访问factory.createStreamWriter()
字段。 。
但是对于您的WebSockets用例,您实际上不需要完全对称的有线格式-您只需要通过有线将有效负载发送到服务器并对其进行解码,然后编写自己的回复并发送即可回到客户。进入客户端后,您的serializer
消息将正确读取该响应有效载荷。
尽管我从不劝阻某人重新发明轮子,但也请考虑使用我之前链接的gwt websocket项目,因为它已经解决了许多这些问题。当然,它并不是完美的,但是随着我们将其作为更新的GWT-RPC模块中的一流功能,它与我们之间的距离越来越近了。