2013-05-28 27 views
0

我想使用泛型模型通過websocket從服務器到客戶端廣播不同的數據。如何使用SimpleJson序列化Java泛型

類使用SimpleJson被序列化:Unfortunatley我同時想序列化下面的類結構總是得到一個錯誤

public class UpdateBroadcastMessageData { 
    private List<UpdateBroadcastModel<? extends Object>> models = new ArrayList<UpdateBroadcastModel<? extends Object>>(); 

    public void clearModels() { 
     ... 
    } 

    public void addModel(Object model) { 
     ... 
    } 

    public void removeModel(Object model) { 
     ... 
    } 
} 

public class UpdateBroadcastModel<T extends Object> { 
    private String clazz = null; 
    private T payload = null; 
    ... 
} 

我JsonUtil類總是拋出的消息「無法轉換成JSON」。

import org.codehaus.jackson.map.ObjectMapper; 

public class JsonUtil { 
    private static ObjectMapper mapper = new ObjectMapper(); 

    public static String convertToJson(Object object) { 
    try { 
     return mapper.writeValueAsString(object); 
    } catch (Exception e) { 
     log.error("Could not convert Object to JSON", e); 
     return ""; 
    } 
} 

public static <T> T convertToObject(String json, Class<T> clazz) { 
    try { 
     return mapper.readValue(json, clazz); 
    } catch (Exception e) { 
     log.error("Could not convert JSON to Object", e); 
     return null; 
    } 
} 
} 

有人可以幫助我,告訴我該怎麼做才能夠序列化上面的數據結構?

該錯誤指的是converttoJson方法。這裏是堆棧跟蹤:

ERROR [pool-3-thread-1][JsonUtil:16] Could not convert Object to JSON 
org.codehaus.jackson.map.JsonMappingException: No serializer found for class 
...UpdateBroadcastMessageData and no properties discovered to create BeanSerializer 
(to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS)) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider$1.serialize(StdSerializerProvider.java:62) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:296) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:224) 
    at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:1512) 
    at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:1262) 
    at ...JsonUtil.convertToJson(JsonUtil.java:14) 
    at ...CommitPoiTokenAction.doProcess(CommitPoiTokenAction.java:118) 
    at ...BaseWebSocketTokenAction.processMessage(BaseWebSocketTokenAction.java:29) 
    at ...WebSocketListener$1.run(WebSocketListener.java:145) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:722) 
pool-3-thread-1: code=81 len=118 

在此先感謝。 faiko

+1

哪種方法失敗 - 是convertToJson或convertToObject?你可以添加異常堆棧跟蹤? – gkamal

+0

我添加了上面的堆棧跟蹤。它在convertToJson中失敗 – faiko

+2

你在這些類中有getter/setter方法(屬性)嗎?傑克遜默認使用getter方法將java對象序列化爲json和setter方法來做相反的處理。從例外看來,類沒有任何getter/setter方法。 – gkamal

回答

0

聲明你的ObjectMapper而不是類的方法。

正如你在堆棧跟蹤中看到的,當它試圖序列化時,你的錯誤是由org.codehaus.jackson.map.ObjectMapper...造成的。如果你沒有在方法中聲明它,你沒有對象映射器,因爲你沒有用構造函數實例化對象,然後你沒有映射器。

public static String convertToJson(Object object) { 
    ObjectMapper mapper = new ObjectMapper();   
    try { 
     return mapper.writeValueAsString(object); 
    } catch (Exception e) { 
     throw new RuntimeException("Could not convert Object to JSON.", e); 
    } 
} 

public static <T> T convertToObject(String json, Class<T> clazz) { 
    ObjectMapper mapper = new ObjectMapper(); 
    try { 
     return mapper.readValue(json, clazz); 
    } catch (Exception e) { 
     throw new RuntimeException("Could not convert JSON to Object.", e); 
    } 
} 

我必須建議你以更好的方式捕捉你的異常。如果你的應用程序拋出錯誤,你必須拋出該錯誤而不是忽略它。使用throw new RuntimeException("Could not convert JSON to <whatever>", e);

UPDATE

不要忘了在類聲明getter/setter方法。

+0

sry,但這並不能解決問題... – faiko

+1

@faiko仍然拋出相同的異常?我剛纔看到你忘了宣佈制定者和獲得者。嘗試聲明它們。 – DaGLiMiOuX

+0

aaahhh解決了我的問題...我只是忘記在UpdateBroadcastMessageData中爲列表模型聲明getter和setter ...感謝您的幫助:) – faiko

0

我認爲你必須使用java bean來序列化你的對象。 http://en.wikipedia.org/wiki/JavaBeans

事實上,

類必須有一個公共的默認構造函數(與無參數)。這允許在編輯和激活框架中輕鬆實例化。

根據標準命名約定,必須可以使用get,set,is(用於布爾屬性而不是get)和其他方法(所謂的訪問器方法和增變器方法)訪問類屬性。這允許在框架內輕鬆自動檢查和更新bean狀態,其中許多包括各種類型屬性的自定義編輯器。安裝者可以有一個或多個參數。

該類應該是可序列化的。 [這允許應用程序和框架來可靠地保存,存儲,並以獨立的虛擬機及臺的恢復Bean的狀態。]

所以,你UpdateBroadcastMessageData類必須符合這些指標分析。