【问题标题】:json rootelement is showing ArrayList instead of @JsonRootName("TestClass") as root element in JSON responsejson rootelement 在 JSON 响应中显示 ArrayList 而不是 @JsonRootName("TestClass") 作为根元素
【发布时间】:2018-12-20 13:45:07
【问题描述】:

我正在开发 maven SpringBoot 微服务应用程序,我希望 json 字符串带有我提到的根元素,但它给了我带有 ArrayList 作为根元素的 json 字符串。

报告了很多类似的问题,但没有一个解决方案适合我。

预计是

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

实际的 json 响应看起来像

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

POJO 模型类

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

应用配置文件

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

【问题讨论】:

    标签: json spring-boot jackson spring-boot-maven-plugin spring-jersey


    【解决方案1】:

    试试下面的代码。

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

    使用任一选项输出:

    {
      "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"
      } ]
    }
    

    另一种选择是: 只需使用 ObjectWriter withRootName 方法。但是,这对于转换为 json 很有用。在阅读时,您将再次需要自定义阅读来列出。

    即使用以下内容,而不在您的原始代码中设置 SerializationFeature.WRAP_ROOT_VALUE 和 DeserializationFeature.UNWRAP_ROOT_VALUE。

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

    【讨论】:

    • 这应该被标记为正确答案。它具有声明单独的 POJO 来保存列表和使用实际根名称编写 objectMapper 的选项。就我个人而言,我更喜欢后者,而第一个只是一个 hack 并且使代码库混乱
    猜你喜欢
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 2016-08-21
    • 2016-02-15
    相关资源
    最近更新 更多