使用Java的Jackson中的通用对象序列化

时间:2011-02-14 16:32:16

标签: java json jackson

我想在字符串{"a": 1.0}中读取通用Java对象,同时保持相同的字符串格式。但是,当我尝试时,杰克逊自动将内部表示更改为{a = 1}。换句话说,如何才能获得以下代码来打印{"a": 1.0}而不是{a = 1}?请注意,我必须将其作为Object读取(由于其他程序限制)。

import org.codehaus.jackson.map.ObjectMapper;

public class Main {

    public static void main(String[] args) {
        try
    {
            ObjectMapper mapper = new ObjectMapper();
            Object myObject = mapper.readValue("{\"a\": 1.0}", Object.class);
            System.out.println(myObject.toString());            
    }
    catch (Exception e)
    {
        e.printStackTrace();
      System.err.println(e.getMessage()); 
    }
    }

}

4 个答案:

答案 0 :(得分:7)

创建的对象将是一个地图(与其他注释一样),因此其toString会生成您所看到的内容{a = 1}。要让代码打印出更接近输入值的代码,您需要使用Jackson将其写回来,例如:

System.out.println(mapper.writeValueAsString(myObject));

这给了我相信你正在寻找的东西:

{"a":1.0}

换句话说,Jackson已将您的输入字符串反序列化为任意Java对象。当您在对象上调用toString时,当然会使用自己的toString。这可以随意编写对象,包括使用Object中的方法。要重现输入字符串,您必须使用Jackson来序列化我们的对象。

答案 1 :(得分:3)

您需要一个与所需json结构匹配的现有类。对象不是这样的类。如果需要,您仍然可以将其称为Object

Object myObject = mapper.readValue("{\"a\": 1.0}", SomeClass.class);

答案 2 :(得分:2)

如果使用调试器,您将看到返回的Object的类型为LinkedHashMap。所以你看到的是LinkedHashMap.toString()的输出。杰克逊没有办法改变它,所以你可以将它转换为Map并自己创建String或者请求另一个为你生成JSON字符串的返回类型:

if(myObject instanceof Map<?, ?>){
    final Map<?, ?> map = (Map<?, ?>) myObject;
    final StringBuilder sb = new StringBuilder("{");
    boolean first = true;
    for(final Entry<?, ?> entry : map.entrySet()){
        if(first){
            first = false;
        } else{
            sb.append(",");
        }
        sb.append("\n\t'")
            .append(entry.getKey())
            .append("':'")
            .append(entry.getValue())
            .append("'");
    }
    if(!first){
        sb.append("\n");
    }
    sb.append("}");
    System.out.println(sb.toString());

} else{
    System.out.println(myObject);
}

<强>输出:

{
    'a':'1.0'
}

答案 3 :(得分:2)

当Jackson被告知将JSON绑定到Object.class时,它就是这样做的;但由于它没有关于JSON中可能存在的内容(或者可能想要使用的类)的先验知识,因此它必须使用大多数基本Java类型:地图,列表,数字,布尔值和字符串。所以任何JSON对象都由Map表示;按列表的JSON数组,依此类推。

如果需要自定义对象,则必须指定其类型;或者,在序列化时,启用包含显式类型信息(“多态类型处理”)。这将添加类名或类型名称,并可用于反序列化为精确类型。

要做到这一点,要么自己(或其中一个超类型)必须使用@JsonTypeInfo注释;或者,如果它是Object属性,则为@JsonTypeInfo属性(字段或方法)。