简体   繁体   English

将JSON字符串转换为“ Object.class”

[英]Convert JSON string to “Object.class”

I am currently trying to use Jackson to turn an object into a JSON string this was easily done by 我目前正在尝试使用Jackson将对象转换为JSON字符串,这很容易实现

public byte[] toJSON(Object obj) throws IOException {
        ObjectMapper map = new ObjectMapper();
        return map.writeValueAsString(obj).getBytes();
    }

Where i run into trouble is when i was to take the array of bytes and turn them into an Object. 我遇到麻烦的地方是当我要获取字节数组并将其转换为对象时。 Currently i have: 目前我有:

public Object toObject(byte[] bytes) throws IOException, ClassNotFoundException {
    ObjectMapper map = new ObjectMapper();
    return (Object)map.readValue(bytes, Object.class);
}

I successfully convert an object to a JSON string but the Object returned from the toObject method is always a LinkedHashMap instead of the object that was initially turned into the JSON string. 我已成功将对象转换为JSON字符串,但从toObject方法返回的对象始终是LinkedHashMap,而不是最初转换为JSON字符串的对象。

Sorry if i did a poor job communicating my problem but ill try to sum it up simply. 抱歉,如果我在传达我的问题方面做得很差,但是生病了,请尝试简单地总结一下。 I want my code to be able to do the following: 我希望我的代码能够执行以下操作:

MyClass someObject = new MyClass();
String json = toJSON(someObject);
Object tempObject = toObject(json);
MyClass sameObject = (MyClass) tempObject;

this code currently throws the following: 该代码当前引发以下内容:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.MyClass

Any help on the matter would be appreciated! 任何帮助的事情将不胜感激!

You are requesting an Object , so Jackson creates one Object it knows it can create: a Map . 您正在请求一个Object ,因此Jackson创建了一个它可以创建的ObjectMap JSON array would become a List and so on. JSON数组将成为List等。

If you want MyClass , you must request it explicitly, or, if you want a general-purpose serialization/deserialization, for inclusion of type identifier, as suggested by @csd. 如果要使用MyClass ,则必须显式地请求它,或者,如果要通用的序列化/反序列化,则必须包含@csd建议的类型标识符。

First, I'm a little confused why you need to deal with byte[] at all. 首先,我有些困惑,为什么您根本需要处理byte[] objectMapper.writeVaueAsString(obj) gives you a perfectly good String with the JSON representation of your object. objectMapper.writeVaueAsString(obj)使用对象的JSON表示形式为您提供了一个非常好的String If you need to convert to byte[] then you need to convert back to String before calling readValue . 如果需要转换为byte[]则需要在调用readValue之前转换回String

But putting that aside for now, let's suppose you've got that String containing the JSON. 但是暂时将其放在一边,让我们假设您已经包含了包含JSON的String By default, Jackson isn't smart enough to know (from looking at the JSON alone) what Java class to instantiate when you call readValue . 默认情况下,Jackson不够聪明,无法(仅通过查看JSON来)知道在调用readValue时要实例化哪个Java类。 In your example, you pass in Object.class , which isn't very helpful for Jackson since EVERY object in Java extends from Object . 在您的示例中,您传入了Object.class ,这对于Jackson并不是很有用,因为Java中的每个对象都从Object扩展而来。 So in that case, it chooses its built-in default, which is to build a Map (in particular, a LinkedHashMap ) with keys and values as listed in the JSON. 因此,在这种情况下,它将选择其内置默认值,即使用JSON中列出的键和值构建Map (尤其是LinkedHashMap )。

As one commenter pointed out, you can give Jackson a hint and pass MyClass.class as the second parameter to readValue (instead of Object.class ). 正如一个评论者指出的那样,您可以给Jackson提示,并将MyClass.class作为第二个参数传递给readValue (而不是Object.class )。 If you did that, then JSON will create an instance of MyClass at the beginning of readValue . 如果这样做,那么JSON将在readValue的开头创建MyClass的实例。 And when it sees something like " foo: 43 " in the JSON, it'll try to find a field or setter (ie public int foo; or public void setFoo(int f) ) in MyClass and set the value accordingly. 并且当它在JSON中看到类似“ foo: 43 ”的内容时,它将尝试在MyClass查找字段或设置器(即public int foo;public void setFoo(int f) )并相应地设置值。

If you don't know ahead of time what type of object it is (ie what value to pass as the second parameter to readValue ) then there are other options. 如果您事先不知道对象是什么类型(即,将什么值作为第二个参数传递给readValue ),那么还有其他选择。 One of example of this is to require that your JSON objects have a class property that Jackson will use as a hint for which type of Java object to create. 其中一个示例是要求您的JSON对象具有一个class属性,Jackson将使用class属性来提示创建哪种类型的Java对象。 Here's what that code might look like: 该代码可能如下所示:

// This annotation tells Jackson to include the class name as
// a "class" property when *writing* JSON.
@JsonTypeInfo(include=As.PROPERTY, use=Id.CLASS, property="class")
public class MyClass {
    public int foo;
}

This will make your JSON look like this: 这将使您的JSON如下所示:

{ "class":"MyClass", foo:0 }

Then in your code to read the object, do this: 然后在代码中读取对象,执行以下操作:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enableDefaultTypingAsProperty(DefaultTyping.JAVA_LANG_OBJECT, "class");
// Note Object.class as second parameter.  Jackson will find the "class"
// property in the JSON and use it to determine which class to make.
MyClass foo = (MyClass) objectMapper.readValue(jsonString, Object.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM