我有以下课程:
public class Message {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
默认情况下,当使用Jackson将实例转换为JSON时,我得到:
{"text":"Text"}
我想得到:
{"message":{"text":"Text"}}
我可以使用JAXB / Jackson注释来实现我的目标吗?
作为一种解决方法,我可以用另一个类包装我的类:
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注释来实现我的目标吗?
感谢。
答案 0 :(得分: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_ELEMENT
和DeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT
。如果你想更改包装器名称(默认情况下它只是非限定类名),你可以使用@JsonRootName
注释
Jackson 2.0通过ObjectReader
和ObjectWriter
以及JAX-RS注释添加了更多动态选项。
答案 1 :(得分: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;
}
}
答案 2 :(得分:2)
如果您不介意json在m
中拥有大写message
,那么最简单的方法就是使用@JsonTypeInfo
为您的班级添加注释。
你会添加:
@JsonTypeInfo(include=As.WRAPPER_OBJECT, use=Id.NAME)
public class Message {
// ...
}
获取{"Message":{"text":"Text"}}
答案 3 :(得分:2)
在Jackson 2.x中,可以使用以下命令启用包装程序,而无需在ObjectMapper中添加其他属性
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
@JsonTypeName(value = "student")
public class Student {
private String name;
private String id;
}
答案 4 :(得分:1)
如果使用spring,则在application.properties
文件中添加以下内容: -
spring.jackson.serialization.WRAP_ROOT_VALUE =真
然后在您要序列化的任何类上使用@JsonRootName
注释。 e.g。
@JsonRootName("user")
public class User {
private String name;
private Integer age;
}
答案 5 :(得分:0)
更简单/更好的方法:
@JsonRootName(value = "message")
public class Message { ...}
然后使用
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...
答案 6 :(得分:0)
我创建了一个包含@JsonWrapped批注的小型jackson模块,该模块解决了该问题。参见代码:https://github.com/mwerlitz/jackson-wrapped
您的课程将如下所示:
public class Message {
@JsonWrapped("message")
private String text;
}