Jackson JSON 没有字段名的序列化
Jackson JSON Serialization without field name
我有一个 JAVA POJO,它有很多字段。其中一个字段是 Map<String, Object>
,我正在为其使用 Custom JsonSerializer
,因为它可以有多种类型的 Objects
。我只想知道如何避免仅针对此 Map<String,Object>
字段对 fieldname
进行序列化。对于 POJO 中的所有其他字段,我想要字段名称,但仅此而已,我想将其删除。
截至目前,当使用 Jackson
searlizer 时,我得到以下输出:
{
"isA" : "Human",
"name" : "Batman",
"age" : "2008",
"others" : {
"key1" : "value1",
"key2" : {
"key3" : "value3"
},
"key5" : {
"key4" : "One",
"key4" : "Two"
}
}
}
我想获得以下输出:(我只想删除 Map<String,Object>
字段名称但保留其子项。)
{
"isA" : "Human",
"name" : "Batman",
"age" : "2008",
"key1" : "value1",
"key2" : {
"key3" : "value3"
},
"key5" : {
"key4" : "One",
"key4" : "Two"
}
}
以下是我的 Human.class
POJO,它被 ObjectMapper
使用:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@NoArgsConstructor
@ToString
class Human {
private String isA;
private String name;
private String age;
@JsonSerialize(using = MyCustomSearlize.class)
private Map<String, Object> others = new HashMap<>();
}
以下是我的 Custom searlizer
,它在搜索过程中被 MAP 使用:
class MyCustomSearlize extends JsonSerializer<Map<String, Object>> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
recusiveSerializer(value, gen, serializers);
gen.writeEndObject();
}
public void recusiveSerializer(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
for (Map.Entry<String, Object> extension : value.entrySet()) {
if (extension.getValue() instanceof Map) {
//If instance is MAP then call the recursive method
gen.writeFieldName(extension.getKey());
gen.writeStartObject();
recusiveSerializer((Map) extension.getValue(), gen, serializers);
gen.writeEndObject();
} else if (extension.getValue() instanceof String) {
//If instance is String directly add it to the JSON
gen.writeStringField(extension.getKey(), (String) extension.getValue());
} else if (extension.getValue() instanceof ArrayList) {
//If instance if ArrayList then loop over it and add it to the JSON after calling recursive method
for (Object dupItems : (ArrayList<Object>) extension.getValue()) {
if (dupItems instanceof Map) {
gen.writeFieldName(extension.getKey());
gen.writeStartObject();
recusiveSerializer((Map) dupItems, gen, serializers);
gen.writeEndObject();
} else {
gen.writeStringField(extension.getKey(), (String) dupItems);
}
}
}
}
}
}
以下是我的Main
class:
public class Main {
public static void main(String[] args) throws JsonProcessingException {
Human person = new Human();
person.setName("Batman");
person.setAge("2008");
Map<String, Object> others = new HashMap<>();
others.put("key1", "value1");
Map<String, Object> complex = new HashMap<>();
complex.put("key3", "value3");
others.put("key2", complex);
Map<String, Object> complex2 = new HashMap<>();
List<String> dup = new ArrayList<>();
dup.add("One");
dup.add("Two");
complex2.put("key4", dup);
others.put("key5", complex2);
person.setOthers(others);
final ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
objectMapper.registerModule(simpleModule);
final String jsonEvent = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
System.out.println(jsonEvent);
}
}
以下我尝试过的事情:
- 我试图在
Map
上添加 @JsonValue
但这会删除我所有其他值(姓名、年龄、isA 等)
- 我尝试了
@JsonAnyGetter
这对 Map
和 String
有效,但对 ArrayList
无效。作为我要求的一部分,我在我的应用程序中处理 ArrayList
有点不同。
有没有办法让它与 @JsonSerialize
和 @JsonAnyGetter
一起使用,因为我无法同时使用它们。
有人可以帮忙解决这个问题吗?请指导我找到适当的文档或解决方法,非常感谢。
从 wiki page 看来,@JsonUnwrapped
注释应该可以满足您的要求。
@JsonUnwrapped: property annotation used to define that value should be "unwrapped" when serialized (and wrapped again when deserializing), resulting in flattening of data structure, compared to POJO structure.
class 的 Javadoc 也有一个看起来合适的例子。
如另一个答案中所述,@JsonUnwrapped
可能有效,但我使用以下方法使其正常工作。在这里发帖,因为它对以后的人有帮助:
我在 Map
的 Getter
方法上添加了 @JsonAnyGetter
和 @JsonSearlize
并让它工作。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@NoArgsConstructor
@ToString
class Human {
private String isA;
private String name;
private String age;
@JsonIgnore
private Map<String, Object> others = new HashMap<>();
@JsonAnyGetter
@JsonSerialize(using = MyCustomSearlize.class)
public Map<String,Object> getOther(){
return others;
}
}
在 MyCustomSearlize
class 代码中,我删除了开始和结束对象
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
recusiveSerializer(value, gen, serializers);
}
我有一个 JAVA POJO,它有很多字段。其中一个字段是 Map<String, Object>
,我正在为其使用 Custom JsonSerializer
,因为它可以有多种类型的 Objects
。我只想知道如何避免仅针对此 Map<String,Object>
字段对 fieldname
进行序列化。对于 POJO 中的所有其他字段,我想要字段名称,但仅此而已,我想将其删除。
截至目前,当使用 Jackson
searlizer 时,我得到以下输出:
{
"isA" : "Human",
"name" : "Batman",
"age" : "2008",
"others" : {
"key1" : "value1",
"key2" : {
"key3" : "value3"
},
"key5" : {
"key4" : "One",
"key4" : "Two"
}
}
}
我想获得以下输出:(我只想删除 Map<String,Object>
字段名称但保留其子项。)
{
"isA" : "Human",
"name" : "Batman",
"age" : "2008",
"key1" : "value1",
"key2" : {
"key3" : "value3"
},
"key5" : {
"key4" : "One",
"key4" : "Two"
}
}
以下是我的 Human.class
POJO,它被 ObjectMapper
使用:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@NoArgsConstructor
@ToString
class Human {
private String isA;
private String name;
private String age;
@JsonSerialize(using = MyCustomSearlize.class)
private Map<String, Object> others = new HashMap<>();
}
以下是我的 Custom searlizer
,它在搜索过程中被 MAP 使用:
class MyCustomSearlize extends JsonSerializer<Map<String, Object>> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
recusiveSerializer(value, gen, serializers);
gen.writeEndObject();
}
public void recusiveSerializer(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
for (Map.Entry<String, Object> extension : value.entrySet()) {
if (extension.getValue() instanceof Map) {
//If instance is MAP then call the recursive method
gen.writeFieldName(extension.getKey());
gen.writeStartObject();
recusiveSerializer((Map) extension.getValue(), gen, serializers);
gen.writeEndObject();
} else if (extension.getValue() instanceof String) {
//If instance is String directly add it to the JSON
gen.writeStringField(extension.getKey(), (String) extension.getValue());
} else if (extension.getValue() instanceof ArrayList) {
//If instance if ArrayList then loop over it and add it to the JSON after calling recursive method
for (Object dupItems : (ArrayList<Object>) extension.getValue()) {
if (dupItems instanceof Map) {
gen.writeFieldName(extension.getKey());
gen.writeStartObject();
recusiveSerializer((Map) dupItems, gen, serializers);
gen.writeEndObject();
} else {
gen.writeStringField(extension.getKey(), (String) dupItems);
}
}
}
}
}
}
以下是我的Main
class:
public class Main {
public static void main(String[] args) throws JsonProcessingException {
Human person = new Human();
person.setName("Batman");
person.setAge("2008");
Map<String, Object> others = new HashMap<>();
others.put("key1", "value1");
Map<String, Object> complex = new HashMap<>();
complex.put("key3", "value3");
others.put("key2", complex);
Map<String, Object> complex2 = new HashMap<>();
List<String> dup = new ArrayList<>();
dup.add("One");
dup.add("Two");
complex2.put("key4", dup);
others.put("key5", complex2);
person.setOthers(others);
final ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
objectMapper.registerModule(simpleModule);
final String jsonEvent = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
System.out.println(jsonEvent);
}
}
以下我尝试过的事情:
- 我试图在
Map
上添加@JsonValue
但这会删除我所有其他值(姓名、年龄、isA 等) - 我尝试了
@JsonAnyGetter
这对Map
和String
有效,但对ArrayList
无效。作为我要求的一部分,我在我的应用程序中处理ArrayList
有点不同。
有没有办法让它与 @JsonSerialize
和 @JsonAnyGetter
一起使用,因为我无法同时使用它们。
有人可以帮忙解决这个问题吗?请指导我找到适当的文档或解决方法,非常感谢。
从 wiki page 看来,@JsonUnwrapped
注释应该可以满足您的要求。
@JsonUnwrapped: property annotation used to define that value should be "unwrapped" when serialized (and wrapped again when deserializing), resulting in flattening of data structure, compared to POJO structure.
class 的 Javadoc 也有一个看起来合适的例子。
如另一个答案中所述,@JsonUnwrapped
可能有效,但我使用以下方法使其正常工作。在这里发帖,因为它对以后的人有帮助:
我在 Map
的 Getter
方法上添加了 @JsonAnyGetter
和 @JsonSearlize
并让它工作。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@NoArgsConstructor
@ToString
class Human {
private String isA;
private String name;
private String age;
@JsonIgnore
private Map<String, Object> others = new HashMap<>();
@JsonAnyGetter
@JsonSerialize(using = MyCustomSearlize.class)
public Map<String,Object> getOther(){
return others;
}
}
在 MyCustomSearlize
class 代码中,我删除了开始和结束对象
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
recusiveSerializer(value, gen, serializers);
}