Java 如何在Jackson生成的JSON中将列表包装为顶级元素

Java 如何在Jackson生成的JSON中将列表包装为顶级元素,java,json,jackson,Java,Json,Jackson,我遇到了一个问题,我试图包括一个列表作为根节点,但我似乎无法得到这个。让我解释一下。假设我们有一个类“TestClass” 现在,在一些实用方法中,这就是我所做的 String utilityMethod(){ List<TestClass> list = someService.getList(); new ObjectMapper().writeValueAsString(list); } 我试着用 objMapper.getSerializationConfig

我遇到了一个问题,我试图包括一个列表作为根节点,但我似乎无法得到这个。让我解释一下。假设我们有一个类“TestClass”

现在,在一些实用方法中,这就是我所做的

String utilityMethod(){
   List<TestClass> list = someService.getList();
   new ObjectMapper().writeValueAsString(list); 
}
我试着用

objMapper.getSerializationConfig().set(Feature.WRAP_ROOT_VALUE, true);
但是,我似乎还是不明白


现在,我正在创建一个Map,我编写它是为了实现我正在尝试做的事情,这是可行的,但显然这是一个黑客行为。有人能帮我找到一个更优雅的解决方案吗?谢谢

我希望基本想法是:

class UtilityClass {
    List listOfTestClasses;
    UtilityClass(List tests) {
        this.listOfTestClasses = tests;
    }
}

String utilityMethod(){
    List<TestClass> list = someService.getList();
    UtilityClass wrapper = new UtilityClass(list);
    new ObjectMapper().writeValueAsString(wrapper); 
}
类实用类{
测试类别列表;
实用类(列表测试){
this.listOfTestClasses=测试;
}
}
字符串实用方法(){
List List=someService.getList();
UtilityClass包装器=新UtilityClass(列表);
新建ObjectMapper().writeValueAsString(包装器);
}

不幸的是,即使启用了
WRAP\u ROOT\u VALUE
功能,您仍然需要额外的逻辑来控制序列化Java集合时生成的根名称(有关详细信息,请参阅)。这使您可以选择:

  • 使用holder类定义根名称
  • 使用地图
  • 使用自定义
以下是说明三种不同选项的代码:

public class TestClass {
    private String propertyA;

    // constructor/getters/setters
}

public class TestClassListHolder {

    @JsonProperty("ListOfTestClasses")
    private List<TestClass> data;

    // constructor/getters/setters
}

public class TestHarness {

    protected List<TestClass> 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<String, List<TestClass>> dataMap = new HashMap<String, List<TestClass>>(
                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()));
    }
}
公共类TestClass{
私有字符串属性a;
//构造函数/获取器/设置器
}
公共类TestClassListHolder{
@JsonProperty(“ListOfTestClasses”)
私人名单数据;
//构造函数/获取器/设置器
}
公共类TestHarness{
受保护列表getTestList(){
返回Arrays.asList(新TestClass(“PropertyValue”),新TestClass(
“其他财产价值”);
}
@试验
public void testSerializeTestClassListDirectly()引发异常{
最终ObjectMapper映射器=新ObjectMapper();
configure(SerializationFeature.WRAP\u ROOT\u值,true);
System.out.println(mapper.writeValueAsString(getTestList());
}
@试验
public void testSerializeTestClassListViaMap()引发异常{
最终ObjectMapper映射器=新ObjectMapper();
最终映射数据映射=新HashMap(
4);
put(“ListofTestClass”,getTestList());
System.out.println(mapper.writeValueAsString(dataMap));
}
@试验
public void testSerializeTestClassListViaHolder()引发异常{
最终ObjectMapper映射器=新ObjectMapper();
最终TestClassListHolder=新TestClassListHolder();
setData(getTestList());
System.out.println(mapper.writeValueAsString(holder));
}
@试验
public void testSerializeTestClassListViaWriter()引发异常{
最终ObjectMapper映射器=新ObjectMapper();
final ObjectWriter writer=mapper.writer().withRootName(
“测试类别列表”);
System.out.println(writer.writeValueAsString(getTestList());
}
}
输出:

{“ArrayList”:[{“propertyA”:“PropertyValue”},{“propertyA”:“someOtherPropertyValue”}]}
{“ListOfTestClasses”:[{“propertyA”:“PropertyValue”},{“propertyA”:“someOtherPropertyValue”}]}
{“ListOfTestClasses”:[{“propertyA”:“PropertyValue”},{“propertyA”:“someOtherPropertyValue”}]}
{“ListofTestClass”:[{“propertyA”:“PropertyValue”},{“propertyA”:“someOtherPropertyValue”}]}


使用
ObjectWriter
非常方便-请记住,使用它序列化的所有顶级对象都将具有相同的根名称。如果不需要,那么使用map或holder类。

这真的是最好的解决方案吗?它与我目前使用的“map”解决方案非常相似。
class UtilityClass {
    List listOfTestClasses;
    UtilityClass(List tests) {
        this.listOfTestClasses = tests;
    }
}

String utilityMethod(){
    List<TestClass> list = someService.getList();
    UtilityClass wrapper = new UtilityClass(list);
    new ObjectMapper().writeValueAsString(wrapper); 
}
public class TestClass {
    private String propertyA;

    // constructor/getters/setters
}

public class TestClassListHolder {

    @JsonProperty("ListOfTestClasses")
    private List<TestClass> data;

    // constructor/getters/setters
}

public class TestHarness {

    protected List<TestClass> 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<String, List<TestClass>> dataMap = new HashMap<String, List<TestClass>>(
                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()));
    }
}