2012-07-10 82 views
0

目前我正在试图用杰克逊把对象变成JSON字符串这很容易被转换JSON字符串“Object.class”

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

完成,其中我遇到麻烦时,我是拿字节数组并将它们变成一个Object。目前,我有:

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 

对此事的任何帮助,将不胜感激!

+1

为什么你要返回一个对象,而是尝试'返回map.readValue(bytes,YourObject.class);' – s106mo 2012-07-10 17:38:59

+0

从你的字节创建一个字符串并在结果字符串上尝试Jackson。 – 2012-07-10 17:59:03

回答

0

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

但是暂且搁置一边,假设你已经得到了包含JSON的String。默认情况下,当你打电话给readValue时,杰克逊不够聪明(仅从查看JSON)实例化的Java类。在你的例子中,你传入Object.class,这对Jackson来说并不是很有用,因为Java中的EVERY对象从Object延伸。因此,在这种情况下,它会选择其内置的默认值,即使用JSON中列出的键和值来构建Map(特别是LinkedHashMap)。

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

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

// 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); 
+0

在需要字节的情况下(或只写入'OutputStream'),也可以使用ObjectMapper.writeValueAsBytes() – StaxMan 2012-07-11 17:46:30

1

你正在申请Object,所以杰克逊创建了一个Object它知道它可以创建:Map。 JSON数组将变为List等等。

如果你想要MyClass,你必须明确地请求它,或者,如果你想要一个通用的序列化/反序列化,包含类型标识符,如@csd所示。