0

我目前正在尝试使用 Jackson 将对象转换为 JSON 字符串,这很容易通过

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

我遇到麻烦的地方是当我要获取字节数组并将它们转换为对象时。目前我有:

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

我成功地将一个对象转换为 JSON 字符串,但从 toObject 方法返回的对象始终是 LinkedHashMap,而不是最初转换为 JSON 字符串的对象。

抱歉,如果我在传达我的问题方面做得不好,但我会尝试简单地总结一下。我希望我的代码能够执行以下操作:

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

此代码当前抛出以下内容:

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

任何有关此事的帮助将不胜感激!

4

2 回答 2

1

您正在请求一个Object,因此杰克逊创建了一个Object它知道它可以创建的:a Map。JSON 数组会变成 aList等等。

如果需要MyClass,您必须明确请求它,或者,如果您想要通用的序列化/反序列化,则按照@csd 的建议包含类型标识符。

于 2012-07-11T17:48:24.877 回答
0

首先,我有点困惑为什么你需要处理byte[]objectMapper.writeVaueAsString(obj)为您提供完美String的对象的 JSON 表示。如果您需要转换为,byte[]则需要String在调用之前转换回readValue

但是暂时先把它放在一边,让我们假设你已经得到了String包含 JSON 的那个。默认情况下,Jackson 不够聪明,无法知道(仅通过查看 JSON)在您调用readValue. 在您的示例中,您传入Object.class,这对 Jackson 没有太大帮助,因为 Java 中的每个对象都扩展自Object. 因此,在这种情况下,它会选择其内置默认值,即使用 JSON 中列出的键和值构建 a Map(特别是 a )。LinkedHashMap

正如一位评论者指出的那样,您可以给杰克逊一个提示并MyClass.class作为第二个参数传递给readValue(而不是Object.class)。如果你这样做了,那么 JSON 将MyClassreadValue. 当它在 JSON 中看到类似“ foo: 43”的内容时,它会尝试在其中找到一个字段或设置器(即public int foo;public void setFoo(int f)MyClass并相应地设置值。

如果您不提前知道它是什么类型的对象(即作为第二个参数传递的值readValue),那么还有其他选项。其中一个示例是要求您的 JSON 对象具有classJackson 将用作提示创建哪种类型的 Java 对象的属性。以下是该代码的样子:

// 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;
}

这将使您的 JSON 看起来像这样:

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

然后在您的代码中读取对象,执行以下操作:

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);
于 2012-07-10T18:00:38.707 回答