2012-05-29 42 views
10

添加addional包裝我有以下類:力傑克遜使用註釋

public class Message { 
    private String text; 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    }  
} 

當使用傑克遜默認實例轉換成JSON我得到:

{"text":"Text"} 

我想獲得:

{"message":{"text":"Text"}} 

有任何JAXB /傑克遜註釋,我可以使用來實現我的目標?

作爲一種變通方法,我可以換我的班與其他類:

public class MessageWrapper { 
    private Message message; 

    public Message getMessage() { 
     return message; 
    } 

    public void setMessage(Message message) { 
     this.message = message; 
    } 
} 

或更通用的解決方案:

public class JsonObjectWrapper<T> { 
    /** 
    * Using a real map to allow wrapping multiple objects 
    */ 
    private Map<String, T> wrappedObjects = new HashMap<String, T>(); 

    public JsonObjectWrapper() { 
    } 

    public JsonObjectWrapper(String name, T wrappedObject) { 
     this.wrappedObjects.put(name, wrappedObject); 
    } 

    @JsonAnyGetter 
    public Map<String, T> any() { 
     return wrappedObjects; 
    } 

    @JsonAnySetter 
    public void set(String name, T value) { 
     wrappedObjects.put(name, value); 
    } 
} 

其中可用於像這樣:

Message message = new Message(); 
message.setText("Text"); 
JsonObjectWrapper<Message> wrapper = new JsonObjectWrapper<Message>("message", message); 

有沒有我可以用來實現的JAXB/Jackson註釋 我的目標?

謝謝。

回答

12

在解決方法:你不絕對需要的getter/setter方法,所以可能只是有:

public class MessageWrapper { 
    public Message message; 
} 

或者是添加便捷構造:

public class MessageWrapper { 
    public Message message; 
    @JsonCreator 
    public MessageWrapper(@JsonProperty("message") Message m) { 
     message = m; 
    } 
} 

有一種方式來增加包裝太;與1.9你可以使用SerializationConfig.Feature.WRAP_ROOT_ELEMENTDeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT。如果你想改變包裝名稱(默認情況下它僅僅是不合格的類名),你可以使用@JsonRootName註釋

傑克遜2.0新增了通過ObjectReaderObjectWriter進一步動態選項,以及JAX-RS註釋。

+0

StaxMan,如果JSON字符串的根元素名稱具有序列化過程中被忽略,不傑克遜1.9要求我們單獨設置'DeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT'功能或添加註釋'的@JsonRootName '也是必需的? – asgs

+1

我必須確認 - UNWRAP可能夠用了;問題是名稱是否必須映射。但即使沒有'@ JsonRootName',也存在默認名稱(簡單的類名),這可能工作正常。 – StaxMan

+0

它的工作!非常感謝。 – asgs

4

很遺憾得知您必須編寫自定義序列化來實現用標記對象包裝類的簡單目標。在編寫自定義序列化程序後,我總結出最簡單的解決方案是通用包裝。這裏有可能是一個更簡單的實現你上面的例子中:

public final class JsonObjectWrapper { 
    private JsonObjectWrapper() {} 

    public static <E> Map<String, E> withLabel(String label, E wrappedObject) { 
     HashMap<String, E> map = new HashMap<String, E>(); 
     map.put(label, wrappedObject); 
     return map; 
    } 
} 
0

一個簡單/更好的方式來做到這一點:

@JsonRootName(value = "message") 
public class Message { ...} 

然後用
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...

2

只要你不介意json的message的首字母爲m,那麼最簡單的方法是用@JsonTypeInfo註釋您的課程。

你可以這樣:

@JsonTypeInfo(include=As.WRAPPER_OBJECT, use=Id.NAME)` 
public class Message { 
    // ... 
} 

得到{"Message":{"text":"Text"}}

0

如果使用的彈簧,然後在application.properties文件中添加以下內容: -

spring.jackson.serialization.WRAP_ROOT_VALUE =真

還有然後在您希望序列化的任何課程上使用@JsonRootName註釋。例如

@JsonRootName("user") 
public class User { 
    private String name; 
    private Integer age; 
}