【问题标题】:Jackson JSON-RPC deserilisation to generic ObjectJackson JSON-RPC 反序列化为通用对象
【发布时间】:2011-02-14 13:13:13
【问题描述】:

我正在尝试使用 Jackson 反序列化 JSON-RPC 对象。 JSON-RPC的格式是:

{“结果”:“某事”,“错误”: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":"optional"}

我试过了:

mapper.readValue(result,objectClass)

其中 result 是结果的 JsonNode 实例(由于某种原因是 LinkedHashMap)和 objectClass 我希望它反序列化到的类。但这不起作用。

我整天都在用不同的方法来做这件事,但我可能不明白杰克逊是谁工作的。

谁能帮我解决这个问题?

提前谢谢你。

【问题讨论】:

    标签: java json jackson json-rpc


    【解决方案1】:

    我理解最初的问题是询问“结果”对象的多态反序列化。

    Jackson 现在有一个可用的内置机制,使用 @JsonTypeInfo@JsonSubTypes 注释。 (ObjectMapper 提供了替代使用注释的方法。)更多信息可在http://wiki.fasterxml.com/JacksonPolymorphicDeserialization 的官方文档中找到。另外,我在http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html 上发布了一些使用示例。

    但是,如果您在反序列化 JSON 时遇到困难,而目标对象中的 JSON 没有通过某个名称标识类型的元素,那么您将遇到自定义反序列化,您必须根据一些对象内容应该是什么类型。我在上面链接的同一博客中的最​​后一个示例演示了这种方法,使用目标对象中存在的特定 JSON 元素来确定类型。

    【讨论】:

    • 您好,我仍在为为此类对象创建尽可能通用的反序列化函数而苦苦挣扎。我想知道我是否只有结果对象(忘记其余的)作为 JSON 字符串,有没有办法创建一个采用“结果”类型并返回反序列化结果的方法?例如,如果结果是 ArrayList 我知道我可以使用 TypeReference ''技术来做到这一点。但是,例如,如果结果是 CustomObject 这将如何工作?我不能使用 TypeReference 可以吗?我会很感激你的反馈。谢谢!
    • 对于 CustomObject 您仍然可以使用 TypeReference 技术。它不仅适用于通用集合。我在jackson-users.ning.com/forum/topics/… 对我自己的问题的回答中发布了一个这样做的例子。这还包括一个使用上下文反序列化器的示例,对于您的情况,这可能不是必需的。
    • 我想你的意思是:TypeReference> fooOfStringType = new TypeReference>() {}; Foo fooOfStringCopy2 = mapper.readValue(fooOfStringJson, fooOfStringType);我想我已经尝试过这个无聊并且没有工作。我会再试一次。谢谢!
    【解决方案2】:

    查看 github 上的 jsonrpc4j:

    https://github.com/briandilley/jsonrpc4j

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,这是我的解决方案。

      我向对象添加了一个字段,因此在构建对象时,我使用类名设置字段值,反序列化时我正在使用 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))

      上面的代码会得到你想要的通用对象。

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2014-02-12
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 2014-03-11
        • 2012-04-12
        • 2020-07-21
        • 2011-12-23
        相关资源
        最近更新 更多