Java 中的 Jackson JSON 序列化 - 将 k/v 对写入根而不是嵌套在 属性 名称中
Jackson JSON serialization in Java - write k/v pairs to root instead of nested in property name
我需要编写一个遵循以下基本格式的 JSON 字符串:
{
"xmlns": {
"nskey1" : "nsurl1",
"nskey2" : "nsurl2"
},
"datakey1": "datavalue1",
"datakey2": "datavalue2"
}
我正在使用以下 class 来呈现数据,并且此 class 的一个实例是使用 Jackson ObjectMapper 序列化的。
public class PayloadData {
public Map<String, String> payloadData = new TreeMap<String, String>();
@JsonProperty("xmlns")
public Map<NamespaceEnum, String> namespaces = new TreeMap<NamespaceEnum, String>();
@JsonAnyGetter
public Map<String, String> getPayloadData() {
return payloadData;
}
}
如果我按原样序列化这个 class 的实例,结果 JSON 将是这样的:
{
"xmlns": {
"nskey1" : "nsurl1",
"nskey2" : "nsurl2"
},
"payloadData": {
"datakey1": "datavalue1",
"datakey2": "datavalue2"
},
"datakey1": "datavalue1",
"datakey2": "datavalue2"
}
根据命名约定,这是有道理的,但我正在寻找一种方法,将 payloadData 映射放置在 JSON 的根上下文中,而不包含包含 属性 的副本标识符和嵌套。我尝试了 很多 各种形式的注释;我试过禁用 ObjectMapper wrap_root_value SerializationFeature;老实说,我觉得我几乎什么都试过了。因此,在我将计算机扔出 window 之前,我需要第二组(甚至更多)眼睛来帮助指出必须非常明显的东西。
在此先感谢您的关注和建议。
编辑:更新了我现在看到的实际输出JSON。数据正在复制,我想删除具有嵌套 属性.
的副本
您可以将 json 数据解析为 HashMap
而不是 class 对象:
public HashMap<String, Object> testJackson(String data) throws IOException {
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String,Object>>() {};
HashMap<String,Object> o = mapper.readValue(data, typeRef);
return o
}
从 HashMap
获取 JSON 数据:
public String getJsonFromMap(HashMap<String, Object> data) {
return new ObjectMapper().writeValueAsString(data);
}
问题是您为 PayloadData
公开了 2 个访问器:public 属性 和 getter,因此它被序列化了两次。如果可能的话,我建议将您的数据 class 重组为不可变的。例如:
public class PayloadData {
private final Map<String, String> payloadData;
private final Map<NamespaceEnum, String> namespaces;
@JsonCreator
public PayloadData(@JsonProperty("xmlns") Map<NamespaceEnum, String> namespaces,
@JsonProperty("payloadData") Map<String, String> payloadData) {
this.namespaces = namespaces;
this.payloadData = payloadData;
}
@JsonAnyGetter
public Map<String, String> getPayloadData() {
return payloadData;
}
@JsonProperty("xmlns")
public Map<NamespaceEnum, String> getNamespaces() {
return namespaces;
}
}
这将为您提供所需的输出,而无需对 ObjectMapper 进行任何配置。
我需要编写一个遵循以下基本格式的 JSON 字符串:
{
"xmlns": {
"nskey1" : "nsurl1",
"nskey2" : "nsurl2"
},
"datakey1": "datavalue1",
"datakey2": "datavalue2"
}
我正在使用以下 class 来呈现数据,并且此 class 的一个实例是使用 Jackson ObjectMapper 序列化的。
public class PayloadData {
public Map<String, String> payloadData = new TreeMap<String, String>();
@JsonProperty("xmlns")
public Map<NamespaceEnum, String> namespaces = new TreeMap<NamespaceEnum, String>();
@JsonAnyGetter
public Map<String, String> getPayloadData() {
return payloadData;
}
}
如果我按原样序列化这个 class 的实例,结果 JSON 将是这样的:
{
"xmlns": {
"nskey1" : "nsurl1",
"nskey2" : "nsurl2"
},
"payloadData": {
"datakey1": "datavalue1",
"datakey2": "datavalue2"
},
"datakey1": "datavalue1",
"datakey2": "datavalue2"
}
根据命名约定,这是有道理的,但我正在寻找一种方法,将 payloadData 映射放置在 JSON 的根上下文中,而不包含包含 属性 的副本标识符和嵌套。我尝试了 很多 各种形式的注释;我试过禁用 ObjectMapper wrap_root_value SerializationFeature;老实说,我觉得我几乎什么都试过了。因此,在我将计算机扔出 window 之前,我需要第二组(甚至更多)眼睛来帮助指出必须非常明显的东西。
在此先感谢您的关注和建议。
编辑:更新了我现在看到的实际输出JSON。数据正在复制,我想删除具有嵌套 属性.
的副本您可以将 json 数据解析为 HashMap
而不是 class 对象:
public HashMap<String, Object> testJackson(String data) throws IOException {
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String,Object>>() {};
HashMap<String,Object> o = mapper.readValue(data, typeRef);
return o
}
从 HashMap
获取 JSON 数据:
public String getJsonFromMap(HashMap<String, Object> data) {
return new ObjectMapper().writeValueAsString(data);
}
问题是您为 PayloadData
公开了 2 个访问器:public 属性 和 getter,因此它被序列化了两次。如果可能的话,我建议将您的数据 class 重组为不可变的。例如:
public class PayloadData {
private final Map<String, String> payloadData;
private final Map<NamespaceEnum, String> namespaces;
@JsonCreator
public PayloadData(@JsonProperty("xmlns") Map<NamespaceEnum, String> namespaces,
@JsonProperty("payloadData") Map<String, String> payloadData) {
this.namespaces = namespaces;
this.payloadData = payloadData;
}
@JsonAnyGetter
public Map<String, String> getPayloadData() {
return payloadData;
}
@JsonProperty("xmlns")
public Map<NamespaceEnum, String> getNamespaces() {
return namespaces;
}
}
这将为您提供所需的输出,而无需对 ObjectMapper 进行任何配置。