Prasad S Deshpande
Prasad S Deshpande

Reputation: 1412

json rootelement is showing ArrayList instead of @JsonRootName("TestClass") as root element in JSON response

I am working on maven SpringBoot microservice application where I expect json string with root element I which I have mentioned but it is giving me json string with ArrayList as rootelement.

There are so many similar questions reported but none of the solutions is working for me.

Expected is

{
    "TestClass": [
        {
            "itemId": "000023",
            "owner": "XYZ",
            "name": "BMW"
        },
        {
            "itemId": "000022",
            "owner": "PQR",
            "name": "GM"
        },
        {
            "itemId": "000021",
            "owner": "xyz",
            "name": "Ford"
        }
    ]
}

Actual json response looks like

{
    "ArrayList": [
        {
            "itemId": "000023",
            "owner": "XYZ",
            "name": "BMW"
        },
        {
            "itemId": "000022",
            "owner": "PQR",
            "name": "GM"
        },
        {
            "itemId": "000021",
            "owner": "xyz",
            "name": "Ford"
        }
    ]
}

POJO model class

import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName("TestClass")
public class TestClass {

    private String itemId;

    private String owner;

    private String name;

    public String getName() {
        return name;
    }

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

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getOwner() {
        return owner;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }
}


package com.apps.partnerecosystem.rest;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import com.teamcenter.hello.Hello;

@Named
@Path("/")
public class TestClassRest {

    private static List<TestClass> clients = new ArrayList<TestClass>();

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<TestClass> getClientes() {
        return clients;
    }


    @GET
    @Path("list")
    @Produces(MediaType.APPLICATION_JSON)
    public List<TestClass> getList() {
        List<TestClass> list = new ArrayList<TestClass>();
        TestClassitem1 = new TestClass();
        item1.setItemId("Test");
        item1.setOwner("deshpapr");
        item1.setName("Test");
        list.add(item1);
        list.add(item1);
        return list;
    }
}

ApplicationConfig file

package com.apps.partnerecosystem.comappspartnerecosystem;

import javax.inject.Named;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;

@Configuration
public class ApplicationConfig {

    @Named
    static class JerseyConfig extends ResourceConfig {
        public JerseyConfig() {
            this.packages("com.apps.partnerecosystem.rest");
        }
    }

    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToEnable(SerializationFeature.WRAP_ROOT_VALUE); // enables
                                                                        // wrapping
                                                                        // for
                                                                        // root
                                                                        // elements
       builder.featuresToEnable(DeserializationFeature.UNWRAP_ROOT_VALUE);
        return builder;
    }
    /*
     * public RestTemplate restTemplate() { RestTemplate restTemplate = new
     * RestTemplate(); restTemplate. return restTemplate; }
     */
}

Upvotes: 0

Views: 1752

Answers (1)

Gireesh Mandhale
Gireesh Mandhale

Reputation: 21

Try the code below.

package com.learn.jackson;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class JacksonConvertList {

    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // Define map which will be converted to JSON

        List<TestClass> list = Stream.of(new TestClass("item1", "owner1", "name1"), new TestClass("item2", "owner1", "name2"),
                new TestClass("item3", "owner1", "name3"), new TestClass("item4", "owner1", "name4")).collect(Collectors.toList());

        // option 1: Use a collection wrapper class as below. 
        TestClassCollection collection = new TestClassCollection(list);
        String arrayToJson = objectMapper.writeValueAsString(collection);

        // option 2: Use Map instead of List.
//      Map<String, List<TestClass>> map = new HashMap<>();
//      map.put(TestClass.class.getSimpleName(), list);
//      String arrayToJson = objectMapper.writeValueAsString(map);

        System.out.println(arrayToJson);

    }

}

# Add this constructor to your class
public TestClass(String itemId, String owner, String name) {
        this.itemId = itemId;
        this.owner = owner;
        this.name = name;
    }

# Add TestClassCollection class 
package com.learn.jackson;

import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;

public class TestClassCollection {

    @JsonProperty("TestClass")
    private List<TestClass> testClass;

    public TestClassCollection (List<TestClass> testClass) {
        this.testClass = testClass;
    }

}

Output using either option:

{
  "TestClass" : [ {
    "itemId" : "item1",
    "owner" : "owner1",
    "name" : "name1"
  }, {
    "itemId" : "item2",
    "owner" : "owner1",
    "name" : "name2"
  }, {
    "itemId" : "item3",
    "owner" : "owner1",
    "name" : "name3"
  }, {
    "itemId" : "item4",
    "owner" : "owner1",
    "name" : "name4"
  } ]
}

Another option is: Simply use ObjectWriter withRootName method. However, this is good for converting to json. While reading you will again need custom reading to list.

i.e. Use following without setting SerializationFeature.WRAP_ROOT_VALUE and DeserializationFeature.UNWRAP_ROOT_VALUE in your original code.

objectMapper.writer().withRootName(TestClass.class.getSimpleName()).writeValueAsString(list);

Upvotes: 1

Related Questions