How to wrap a List as top level element in JSON generated by Jackson

前端 未结 2 473
死守一世寂寞
死守一世寂寞 2020-12-16 04:58

I am running into a problem where I am trying to include a List as the root node, but I can\'t seem to be able to get this. Let me explain. Let\'s say we have a class \"Test

2条回答
  •  佛祖请我去吃肉
    2020-12-16 05:33

    Unfortunately, even with the WRAP_ROOT_VALUE feature enabled you still need extra logic to control the root name generated when serializing a Java collection (see this answer for details why). Which leaves you with the options of:

    • using a holder class to define the root name
    • using a map.
    • using a custom ObjectWriter

    Here is some code illustrating the three different options:

    public class TestClass {
        private String propertyA;
    
        // constructor/getters/setters
    }
    
    public class TestClassListHolder {
    
        @JsonProperty("ListOfTestClasses")
        private List data;
    
        // constructor/getters/setters
    }
    
    public class TestHarness {
    
        protected List getTestList() {
            return Arrays.asList(new TestClass("propertyAValue"), new TestClass(
                    "someOtherPropertyValue"));
        }
    
        @Test
        public void testSerializeTestClassListDirectly() throws Exception {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
            System.out.println(mapper.writeValueAsString(getTestList()));
        }
    
        @Test
        public void testSerializeTestClassListViaMap() throws Exception {
            final ObjectMapper mapper = new ObjectMapper();
            final Map> dataMap = new HashMap>(
                    4);
            dataMap.put("ListOfTestClasses", getTestList());
            System.out.println(mapper.writeValueAsString(dataMap));
        }
    
        @Test
        public void testSerializeTestClassListViaHolder() throws Exception {
            final ObjectMapper mapper = new ObjectMapper();
            final TestClassListHolder holder = new TestClassListHolder();
            holder.setData(getTestList());
            System.out.println(mapper.writeValueAsString(holder));
        }
    
        @Test
        public void testSerializeTestClassListViaWriter() throws Exception {
            final ObjectMapper mapper = new ObjectMapper();
            final ObjectWriter writer = mapper.writer().withRootName(
                    "ListOfTestClasses");
            System.out.println(writer.writeValueAsString(getTestList()));
        }
    }
    

    Output:

    {"ArrayList":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
    {"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
    {"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
    {"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}

    Using an ObjectWriter is very convenient - just bare in mind that all top level objects serialized with it will have the same root name. If thats not desirable then use a map or holder class instead.

提交回复
热议问题