我想在字符串{"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());
}
}
}
答案 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属性(字段或方法)。