Reputation: 1412
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
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