如何重命名JSON序列化与杰克逊根密钥(How to rename root key in JSON

2019-08-21 13:13发布

我使用的杰克逊对象列表的JSON序列化。

以下是我得到:

{"ArrayList":[{"id":1,"name":"test name"}]}

但我想这一点:

{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root name.

下面是我的做法是:

接口:

public interface MyInterface {
    public long getId();
    public String getName();
}

实现类:

@JsonRootName(value = "rootname")
public class MyImpl implements MyInterface {
    private final long id;
    private String name;

    public MyImpl(final long id,final name) {
        this.id = id;
        this.name = name;
    }

   // getters     
}

JSON序列:

public class MySerializer {
    public static String serializeList(final List<MyInterface> lists) {
        //check for null value.Throw Exception
        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        return mapper.writeValueAsString(lists);
    }
}

测试:

final List<MyInterface> list = new ArrayList<MyImpl>();
MyImpl item = new MyImpl(1L,"test name");
list.add(item);
final String json = MySerializer.serializeList(list);
System.out.println(json);

以下是我得到:

{"ArrayList":[{"id":1,"name":"test name"}]}

但我想这一点:

{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root     name.

我已经尝试了所有建议的解决方案,我可以找到,但没能实现我的目标。 我看过:

  • 杰克逊:自定义集合序列化JSON
  • 如何重命名与Java杰克逊JSON的根密钥?
  • 杰克逊:自定义集合序列化JSON

还是我失去了一些东西? 我使用的杰克逊1.9.12这个。 在这方面的任何帮助是值得欢迎的。

Answer 1:

那么,在默认情况下使用杰克逊试图确定根域名要显示的包裹值,当两个注解之一- @XmlRootElement@JsonRootName 。 它预计这一注释是在类型被序列化,否则它会使用简单的名称类型为根的名字。

在你的情况,你是序列化的列表,这就是为什么根的名字是“ArrayList的”(简单类型被序列化的名称)。 列表中的每个元素可以是具有@JsonRootName注释的类型,但该列表本身不是

当你试图总结根值集合,那么你需要定义包裹名称的一些方法:

座/包装类

您可以创建一个包装类来保存列表,与注释定义所需的属性名( 你只需要使用这个方法时,你不具备直接控制ObjectMapper / JSON转化过程 ):

class MyInterfaceList {
    @JsonProperty("rootname")
    private List<MyInterface> list;

    public List<MyInterface> getList() {
        return list;
    }

    public void setList(List<MyInterface> list) {
        this.list = list;
    }
}

final List<MyInterface> lists = new ArrayList<MyInterface>(4);
lists.add(new MyImpl(1L, "test name"));
MyInterfaceList listHolder = new MyInterfaceList();
listHolder.setList(lists);
final String json = mapper.writeValueAsString(listHolder);

对象编写

这是优选的选项。 使用配置ObjectWriter实例来生成JSON。 特别是,我们感兴趣的是withRootName方法:

final List<MyInterface> lists = new ArrayList<MyInterface>(4);
lists.add(new MyImpl(1L, "test name"));
final ObjectWriter writer = mapper.writer().withRootName("rootName");
final String json = writer.writeValueAsString(lists);


Answer 2:

我知道,我迟到了,但我有更好的办法不需要持有人/包装类。 它采用主从注释根密钥。

package com.test;

import com.fasterxml.jackson.annotation.JsonRootName;


@JsonRootName("Products")
public class ProductDTO {
    private String name;
    private String description;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

下面是测试类: -

package com.test;

import java.io.IOException;
import java.util.ArrayList;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;


public class ProductDTOTestCase {
    @Test
    public void testPersistAndFindById() throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        ProductDTO productDTO = new ProductDTO();
        productDTO.setDescription("Product 4 - Test");

        ArrayList<ProductDTO> arrayList = new ArrayList<ProductDTO>();
        arrayList.add(productDTO);

        String rootName = ProductDTO.class.getAnnotation(JsonRootName.class).value();
        System.out.println(mapper.writer().withRootName(rootName).writeValueAsString(arrayList));

    }


}

它会给下面的输出

{"Products":[{"name":null,"description":"Product 4 - Test"}]}


Answer 3:

您需要在类的顶部使用此批注

@JsonTypeName("rootname")



Answer 4:

@JsonTypeName("usuarios")
@JsonTypeInfo(include= JsonTypeInfo.As.WRAPPER_OBJECT,use= JsonTypeInfo.Id.NAME)
public class UsuarioDT extends ArrayList<Usuario> {

    @JsonProperty("rowsAffected")
    private Integer afectados;

    public Integer getAfectados() {
        return afectados;
    }

    public void setAfectados(Integer afectados) {
        this.afectados = afectados;
    }
}


文章来源: How to rename root key in JSON serialization with Jackson