2012-05-29 41 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; 
}