Jackson JSON-RPC 反序列化为通用对象
我正在尝试使用 Jackson 反序列化 JSON-RPC 对象。 JSON-RPC 的格式为:
{ "result": "something", "error": null, "id": 1}
在我的例子中,结果属性是一个通用对象。
我有一个用于反序列化响应的类:
public class JsonRpcResponse {
private Object result;
private JsonRpcError error;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public JsonRpcError getError() {
return error;
}
public void setError(JsonRpcError error) {
this.error = error;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
我可以通过以下方式获取响应对象:
JsonRpcResponse jsonResp = mapper.readValue(response, JsonRpcResponse.class);
我想要一个通用方法,通过将对象的类型(或类(如果你愿意的话)将被反序列化。这样我就可以根据我期望的响应传递任何类型的对象。
例如,我的此类具有两个属性:
public class JsonEventProperties {
private String conditon;
private String usage;
public JsonEventProperties(String condition, String usage) {
this.conditon = condition;
this.usage = usage;
}
public JsonEventProperties() {
throw new UnsupportedOperationException("Not yet implemented");
}
public String getConditon() {
return conditon;
}
public void setConditon(String conditon) {
this.conditon = conditon;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
}
上述情况的响应内的结果对象将是:
"result": {"condition":"test","usage 。
我尝试过:
mapper.readValue(result,objectClass)
其中 result 是结果的 JsonNode 实例(由于某种原因是 LinkedHashMap),而 objectClass 是我希望其反序列化到的类 但这是行不通的。
我一整天都在用不同的方式做这件事,但我可能不明白杰克逊是谁在工作。
谁能帮我解决这个问题吗?
先感谢您。
I am trying to deserialise a JSON-RPC object with Jackson. The format of JSON-RPC is :
{ "result": "something", "error": null, "id": 1}
In my case the result property is an generic Object.
I have a class for deserilising the response:
public class JsonRpcResponse {
private Object result;
private JsonRpcError error;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public JsonRpcError getError() {
return error;
}
public void setError(JsonRpcError error) {
this.error = error;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
I can get the response object with:
JsonRpcResponse jsonResp = mapper.readValue(response, JsonRpcResponse.class);
I want to have a generic method that deserializes this result object by passing to the method the type of the object (or the class if you want) that is going to be deserialized to. This way I can pass any type of object depending of the response I expect.
For example, I have this class with two properties:
public class JsonEventProperties {
private String conditon;
private String usage;
public JsonEventProperties(String condition, String usage) {
this.conditon = condition;
this.usage = usage;
}
public JsonEventProperties() {
throw new UnsupportedOperationException("Not yet implemented");
}
public String getConditon() {
return conditon;
}
public void setConditon(String conditon) {
this.conditon = conditon;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
}
The result object inside the response for the above case will be:
"result": {"condition":"test","usage":"optional"}
I tried:
mapper.readValue(result,objectClass)
where result is a JsonNode intance of the result (Which for some reason is a LinkedHashMap) and objectClass the class I want it to deserialize to. But this is not working.
I busted my head all day with different ways of doing this but I probably do not understand who Jackson works.
Can anyone help me with this?
Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我理解原来的问题是询问“结果”对象的多态反序列化。
Jackson 现在有一个可用的内置机制,使用
@JsonTypeInfo
和@JsonSubTypes
注释。 (ObjectMapper
具有可作为使用注释的替代方法的方法。)更多信息可在官方文档中找到,网址为 http://wiki .fasterxml.com/JacksonPolymorphicDeserialization。另外,我在 http: //programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html。但是,如果您在反序列化 JSON 时遇到困难,而目标对象中没有通过某个名称标识类型的元素,那么您就会陷入自定义反序列化,您必须根据某些对象内容来确定类型应该是什么。我在上面链接的同一博客中的最后一个示例演示了这种方法,它使用目标对象中特定 JSON 元素的存在来确定类型。
I understand the original question to be asking about polymorphic deserialization of the "result" object.
Jackson now has a built-in mechanism available for this, using the
@JsonTypeInfo
and@JsonSubTypes
annotations. (ObjectMapper
has methods available as alternatives to using the annotations.) Further information is available in the official docs at http://wiki.fasterxml.com/JacksonPolymorphicDeserialization. Also, I posted a few use examples of this at http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html.However, if you're stuck deserializing JSON that, in the target object, does not have an element that identifies the type by some name, then you're stuck with custom deserialization, where you'll have to determine based on some object content what the type should be. One of the last examples in the same blog posted I linked above demonstrates this approach, using the existence of particular JSON elements in the target object to determine the type.
在 github 上查看 jsonrpc4j:
https://github.com/briandilley/jsonrpc4j
Check out jsonrpc4j on github:
https://github.com/briandilley/jsonrpc4j
我有同样的问题,这是我的解决方案。
我向对象添加了一个字段,因此在构建对象时,我使用类名设置字段值,在反序列化时我使用
mapper.convertvalue(object, Class.forName(field value)
在你的情况下
private Object result;
在结果对象中再添加一个字段“className”,在序列化该类时,将值“className”设置为您视为结果对象的类的名称。
反序列化对象时
JsonRpcResponse jsonResp = mapper.readValue(response, JsonRpcResponse.class);
在 jsonResp 中,您将得到
Object result, String className
,这里对象的类型为 linkedhashmap现在要转换为你的对象
objectmapper.convertValue(result, Class.forName(className))
上面的代码将为你提供你想要的通用对象。
希望这有帮助
I had the same issue, this was my solution.
I added one more field to the object, so when building the object, i am setting the field value with class name, when deserializing it i am using
mapper.convertvalue(object, Class.forName(field value)
In your case
private Object result;
In the result object add one more field "className", while serializing the class set the value "className" with the name of the class you are treating as result object.
while deserializing the object
JsonRpcResponse jsonResp = mapper.readValue(response, JsonRpcResponse.class);
in jsonResp you will have
Object result, String className
, here the object is of type linkedhashmapNow to convert to your object
objectmapper.convertValue(result, Class.forName(className))
The above code will get you the generic object which you want .
Hope this helps