[英]How to deserialize and return objects from JSON in Java with Gson without knowing the .class a priori?
I am currently working on a thin-client application, where the communication happens through JSON-serialized message objects. 我目前正在开发瘦客户端应用程序,该应用程序通过JSON序列化的消息对象进行通信。 Server serializes the message, sends it through a socket, client receives and deserializes.
服务器将消息序列化,通过套接字发送,客户端接收并反序列化。 Answers happen in the same way.
答案以相同的方式发生。
First, let's assume the message class are defined both on server and client. 首先,假设消息类在服务器和客户端上均已定义。
Problem is that Gson::fromJson
function needs a .class/type object for deserializing via introspection (understandably), but in my application, multiple type of objects can be received without knowing the .class in advance. 问题是
Gson::fromJson
函数需要一个.class / type对象用于通过自省反序列化(可以理解),但是在我的应用程序中,可以接收多种类型的对象,而无需事先知道.class。
My idea was to create a message wrapper like this: 我的想法是创建一个像这样的消息包装器:
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;
}
Or even go further by determining type
param with introspection. 甚至可以通过内省来确定
type
param,从而走得更远。 This solution is great for serializing (I repeat, that is not a problem), but while deserializing I would get the message type and loose the message itself, at least if I don't parse it twice. 这个解决方案非常适合序列化(我再说一遍,这不是问题),但是在反序列化时,我将获得消息类型并释放消息本身,至少如果我不两次解析它。 Specializing MessageWrapper through Java "templating" mechanism brings us back to the original problem (I would have multiple classes to choose from).
通过Java“模板”机制专门化MessageWrapper可以使我们回到最初的问题(我将有多个类可供选择)。
Another idea, was to send a token to identify the message, before the JSON string, like: 另一个想法是在JSON字符串之前发送令牌以标识消息,例如:
Placement={"foo": 2, "bar": "baz"}
Then read the token to determine the .class type. 然后读取令牌以确定.class类型。 This could work, but there is still a problem: how would I return the value from my
receive
function? 这可能有效,但是仍然存在问题: 如何从我的
receive
函数返回值? Of course I could do: 我当然可以:
public Object receive(Reader stream) {}
And force the user to do a downcast, but I'd rather avoid it. 并强迫用户进行向下转换,但我宁愿避免这种情况。
EDIT: this is because the client has a reactor-like structure: it runs in a loop and dispatches messages to appropriate handlers. 编辑:这是因为客户端具有类似反应堆的结构:它在循环中运行并将消息分派到适当的处理程序。
EDIT: 编辑:
Ok, now it's clearer. 好的,现在更清楚了。
What about having a Wrapper with a series of defined Objects? 拥有一个带有一系列已定义对象的包装怎么样? How many handlers do you have?
您有几个处理程序?
I mean something like: 我的意思是:
class HandlerWrapper {
private final Placement placement;
private final Update update;
}
then the client will deserialize this and check for the not-null property: 然后客户端将反序列化并检查not-null属性:
{"placement":{"foo": 2, "bar": "baz"}, "update":null, ...}
I knwo it's not very nice but I cannot think about something else.. : / 我知道这不是很好,但是我不能考虑其他事情。
OLD 旧
I don't think this is actually a problem, because you can say in your specification what kind of object you have to expect from that specific case. 我不认为这实际上是一个问题,因为您可以在规范中说出在特定情况下必须期望什么样的对象。
For example, if you're calling an API to get a User, you will expect a User.class in the Object. 例如,如果您要调用API来获取用户,则将在对象中使用User.class。 The same for an API to get a Book (or whatelse).
获取书籍(或其他书籍)的API同样如此。
(I hope I understood the question) (希望我能理解这个问题)
Using Gson, if you have a reasonable number of possible messages, you could create a class containing all of them (something similar to which @Enrichman wrote, but you don't need to check for nulls...). 使用Gson,如果您有足够数量的可能消息,则可以创建一个包含所有消息的类(类似于@Enrichman编写的类,但无需检查null ...)。 For example if you have the class
例如,如果您有课程
public class Response {
private Placement placement;
private Update update;
//more message types
//getters & setters
}
Then you can deserialize your response with: 然后,您可以使用以下方法反序列化您的响应:
Gson gson = new Gson();
Response response = gson.fromJson(jsonString, Response.class);
And it would deserialize this JSON: 它将反序列化此JSON:
{"placement": {...} }
and this: 和这个:
{"update": {...} }
and this: 和这个:
{"placement": {...}, "update": {...} }
Gson will ignore all the fields in the JSON response that don't correspond to any attribute in your class, so you can use a single class to deserialize multiple responses... Gson将忽略JSON响应中与类中任何属性都不对应的所有字段,因此您可以使用单个类对多个响应进行反序列化...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.