How to rename root key in JSON serialization with Jackson

前端 未结 4 1450
孤城傲影
孤城傲影 2020-12-01 06:47

I am using Jackson for JSON serialization of a list of objects.

Here is what I get:

{\"ArrayList\":[{\"id\":1,\"name\":\"test name\"}]}
相关标签:
4条回答
  • 2020-12-01 06:50
    @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;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 06:51

    I know, I am late , but I have better approach which don't require Holder/Wrapper Class. It picks root key from annotation.

    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;
        }
    }
    

    Here is test class:-

    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));
    
        }
    
    
    }
    

    It will give following output

    {"Products":[{"name":null,"description":"Product 4 - Test"}]}
    
    0 讨论(0)
  • 2020-12-01 06:53

    You need to use this annotation at the top of the class

    @JsonTypeName("rootname")

    0 讨论(0)
  • 2020-12-01 06:54

    Well, by default Jackson uses one of two annotations when trying to determine the root name to be displayed for wrapped values - @XmlRootElement or @JsonRootName. It expects this annotation to be on the type being serialized, else it will use the simple name of the type as the root name.

    In your case, you are serializing a list, which is why the root name is 'ArrayList' (simple name of the type being serialized). Each element in the list may be of a type annotated with @JsonRootName, but the list itself is not.

    When the root value you are trying to wrap is a collection then you need some way of defining the wrap name:

    Holder/Wrapper Class

    You can create a wrapper class to hold the list, with an annotation to define the desired property name (you only need to use this method when you do not have direct control of the ObjectMapper/JSON transformation process):

    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);
    

    Object Writer

    This is the preferable option. Use a configured ObjectWriter instance to generate the JSON. In particular, we are interested in the withRootName method:

    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);
    
    0 讨论(0)
提交回复
热议问题