使用 Java 在 Jackson 中进行通用对象序列化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4994627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:58:58  来源:igfitidea点击:

Generic object serialization in Hymanson with Java

javajsonHymanson

提问by edd

I would like to read in the string {"a": 1.0}as a generic Java Object while keeping the same string format. However, when I try, Hymanson automatically changes the internal representation to {a = 1}. In other words, how can I get the following code to print {"a": 1.0}instead of {a = 1}? Note that, I have to read it in as an Object(due to other program constraints).

我想将字符串{"a": 1.0}作为通用 Java 对象读入, 同时保持相同的字符串格式。但是,当我尝试时,Hymanson 会自动将内部表示更改为{a = 1}. 换句话说,我怎样才能打印下面的代码{"a": 1.0}而不是{a = 1}?请注意,我必须将其读入Object(由于其他程序限制)。

import org.codehaus.Hymanson.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()); 
    }
    }

}

回答by oconnor0

The created object will be a map (like the other comments) and so its toStringproduces what you're seeing, {a = 1}. To get your code to print something closer to your input value, you need to use Hymanson to write it back out with something like:

创建的对象将是一张地图(就像其他评论一样),因此它toString会生成您所看到的{a = 1}. 为了让您的代码打印出更接近您输入值的内容,您需要使用 Hymanson 将其写回,例如:

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

That gives me what I believe you're looking for:

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

{"a":1.0}

In other words, Hymanson has deserialized your input string into an arbitrary Java object. When you call toStringon the object, its own toStringis, of course, used. This can write the object however it pleases, including using the method from Object. To reproduce the input string, you have to use Hymanson to serialize our object back out.

换句话说,Hymanson 已将您的输入字符串反序列化为任意 Java 对象。当您调用toString对象时,toString当然会使用它自己的对象。这可以随心所欲地编写对象,包括使用Object. 要重现输入字符串,您必须使用 Hymanson 将我们的对象序列化。

回答by Bozho

You need an existing class that matches the desired json structure. Object is not such class. You can still refer to it as Object, if that's needed:

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

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

回答by Sean Patrick Floyd

If you use a debugger, you will see that the type of the returned Object is LinkedHashMap. So what you see is the output of LinkedHashMap.toString(). There's no way for Hymanson to change that, so you can either cast it to a Map and create the String yourself or ask for another return type that generates the JSON String for you:

如果你使用调试器,你会看到返回的 Object 的类型是LinkedHashMap. 所以你看到的是LinkedHashMap.toString(). Hymanson 无法更改它,因此您可以将其转换为 Map 并自己创建字符串,或者要求另一种返回类型为您生成 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);
}

Output:

输出:

{
    'a':'1.0'
}

回答by StaxMan

When Hymanson is told to bind JSON into Object.class, it does just that; but since it has no a priori knowledge of what might be in that JSON (or what classes one might want to use), it has to use most basic Java types: Maps, Lists, Numbers, Booleans and Strings. So any JSON Object is represented by Map; JSON Array by List, and so on.

当 Hymanson 被告知将 JSON 绑定到 Object.class 时,它就是这样做的;但由于它对 JSON 中可能包含的内容(或人们可能想要使用的类)没有先验知识,因此它必须使用最基本的 Java 类型:地图、列表、数字、布尔值和字符串。所以任何 JSON 对象都由 Map 表示;JSON Array by List,等等。

If you want a custom object, you must specify its type; or, when serializing, enable inclusion of explicit type information ("polymorphic type handling"). This will add either class name, or type name, and can be used to deserialize back to exact type.

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

To do this, either type itself (or one of its supertypes) must use @JsonTypeInfo annotation; or, if it is an Object property, @JsonTypeInfo for property (field or method).

为此,类型本身(或其超类型之一)必须使用 @JsonTypeInfo 注释;或者,如果它是一个 Object 属性,@JsonTypeInfo 用于属性(字段或方法)。