2012-07-10 114 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所示。