GWT SeralizationStreamFactory读者问题

时间:2019-01-28 16:19:13

标签: java gwt web-worker

我有一个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)

1 个答案:

答案 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模块中的一流功能,它与我们之间的距离越来越近了。