我目前正在开发一个瘦客户端应用程序,其中通信通过 JSON 序列化消息对象进行。服务器序列化消息,通过套接字发送,客户端接收和反序列化。答案以同样的方式发生。
首先,假设消息类在服务器和客户端上都定义了。
问题是该Gson::fromJson
函数需要一个 .class/type 对象来通过自省进行反序列化(可以理解),但在我的应用程序中,可以在事先不知道 .class 的情况下接收多种类型的对象。
我的想法是创建一个像这样的消息包装器:
class MessageWrapper {
public class MessageWrapper(Object message, MessageType type) {
this.message = message;
this.type = type;
}
// getters...
public enum MesssageType {
PLACEMENT,
UPDATE,
// ...
}
private final Object message;
private final MessageType type;
}
甚至可以通过type
自省来确定参数。这个解决方案非常适合序列化(我重复一遍,这不是问题),但是在反序列化时,我会得到消息类型并丢失消息本身,至少如果我不解析它两次的话。通过 Java“模板”机制专门化 MessageWrapper 使我们回到最初的问题(我将有多个类可供选择)。
另一个想法是在 JSON 字符串之前发送一个标记来识别消息,例如:
Placement={"foo": 2, "bar": "baz"}
然后读取令牌以确定 .class 类型。这可以工作,但仍然存在一个问题:我将如何从我的receive
函数返回值?我当然可以:
public Object receive(Reader stream) {}
并强迫用户做一个沮丧,但我宁愿避免它。
编辑:这是因为客户端具有类似反应器的结构:它在循环中运行并将消息分派给适当的处理程序。