سؤال

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.

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

Check out jsonrpc4j on github:

https://github.com/briandilley/jsonrpc4j

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 linkedhashmap

Now 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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top