Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson序列化:换行字段_Java_Json_Jackson - Fatal编程技术网

Java Jackson序列化:换行字段

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

当我们打开嵌套对象并将其字段写入主对象时,有一个很好的例子,我需要做一个反向任务

我有一个POJO:

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种可能的方法:

  • 编写自定义序列化程序。但在我看来,编写这样的序列化程序比手工序列化对象要花更多的精力
  • 创建反映JSON正确结构的代理Java对象,并序列化此类代理
  • 在生成JSON后修改它。(我担心重读和重写JSON会有很大的开销)
  • 是否有人制作了这样的序列化程序,或者可能知道使用我需要的结构生成JSON的其他选项

    对于
    自定义序列化程序
    我想重用标准BeanSerializer,我不想手动写出所有字段:

  • 隐藏带注释的字段
  • 写出bean,不带注释的字段,但不要关闭对象。(不要调用
    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解决方案适合您?