Java Jackson序列化:换行字段
当我们打开嵌套对象并将其字段写入主对象时,有一个很好的例子,我需要做一个反向任务 我有一个POJO:Java Jackson序列化:换行字段,java,json,jackson,Java,Json,Jackson,当我们打开嵌套对象并将其字段写入主对象时,有一个很好的例子,我需要做一个反向任务 我有一个POJO: class A { private String id = "id1"; @JsonWrap("properties") private String property1 = "..."; @JsonWrap("properties") private String property2 = "..."; // getters and sett
class A {
private String id = "id1";
@JsonWrap("properties")
private String property1 = "...";
@JsonWrap("properties")
private String property2 = "...";
// getters and setters
}
默认序列化程序将按预期生成
{
"id": "id1",
"property1": "...",
"property2": "..."
}
但是,我的JSON应该匹配一些规范,为此,我需要将property1
和property2
封装在properties
包装器中。因此,结果应该如下所示:
{
"id": "id1",
"properties":
{
"property1": "...",
"property2": "..."
}
}
我不想更改POJO的结构,因此我看到了3种可能的方法:
自定义序列化程序
我想重用标准BeanSerializer,我不想手动写出所有字段:
jgen.writeEndObject();
)你需要改变你的模型
@JsonSerialize(using = ASerializer.class)
class A {
private String id;
private String property1;
private String property2;
// getters and setters
public static class ASerializer extends JsonSerializer<A> {
@Override
public void serialize(A value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("id", value.getId());
jgen.writeObjectFieldStart("properties");
jgen.writeStringField("property1", value.getProperty1());
jgen.writeStringField("property2", value.getProperty2());
jgen.writeEndObject();
jgen.writeEndObject();
}
}
}
输出:
A a = new A();
a.setId("id1");
a.setProperty1("...");
a.setProperty2("...");
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer();
String json = writer.writeValueAsString(a);
System.out.println(json);
{"id":"id1","properties":{"property1":"...","property2":"..."}}
听起来您需要创建自定义序列化程序: 当然,如果要从类似的JSON结构创建Java对象,可能还需要创建自定义反序列化器
请记住,如果发现许多对象具有相似的结构,则始终可以使用反射创建“通用”序列化程序。要在不改变模型的情况下获得该功能,请查看编写自定义序列化程序以完成Jackson本机无法理解的功能。我们对模型类
A
进行注释,说明如何使用已定义的序列化程序,然后使用JsonGenerator
来具体定义我们所追求的结构
@JsonSerialize(using = ASerializer.class)
class A {
private String field1;
private String innerField1;
private String innerField2;
// getters and setters
public static class ASerializer extends JsonSerializer<A> {
@Override
public void serialize(A value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("field1", value.getField1());
jgen.writeObjectFieldStart("wrapper");
jgen.writeStringField("innerField1", value.getInnerField1());
jgen.writeStringField("innerField2", value.getInnerField2());
jgen.writeEndObject();
jgen.writeEndObject();
}
}
}
@JsonSerialize(使用=ASerializer.class)
甲级{
私有字符串字段1;
私有字符串innerField1;
私有字符串innerField2;
//接球手和接球手
公共静态类ASerializer扩展了JsonSerializer{
@凌驾
public void serialize(值、JsonGenerator jgen、SerializerProvider提供程序)
抛出IOException、JsonProcessingException{
jgen.writeStartObject();
writeStringField(“field1”,value.getField1());
jgen.writeObjectFieldStart(“包装器”);
writeStringField(“innerField1”,value.getInnerField1());
writeStringField(“innerField2”,value.getInnerField2());
jgen.writeEndObject();
jgen.writeEndObject();
}
}
}
在本例中,我使用了一个静态内部类,但是您可以根据可见性将序列化程序放置在最适合您的项目结构的任何位置。对于一次性的特例序列化程序,我倾向于这样做。但这正是我不想做的。这将给应用程序的其他层带来困难。我更改了解决方案。通常情况下,此解决方案会夸大您的需要。抱歉,我发布此解决方案时您编辑了您的问题,此答案使用原始字段,但我认为您可以理解。是的,我当然理解,但我想使用BeanSerializer,我不想手动编写所有字段。sgrillon解决方案适合您?