当前位置: 首页 > 面试题库 >

如何将列表包装为杰克逊生成的JSON中的顶级元素

宿镜
2023-03-14
问题内容

我遇到了一个问题,试图将List作为根节点,但似乎无法获得此信息。让我解释。假设我们有一个类“ TestClass”

class TestClass{
    String propertyA;       
}

现在,在某些实用程序方法中,这就是我要做的

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

我试图获取的JSON输出是

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

我尝试使用

objMapper.getSerializationConfig().set(Feature.WRAP_ROOT_VALUE, true);

但是,我似乎仍然做得不好。

现在,我只是创建一个Map
,并编写该代码来实现我要执行的操作,虽然可以,但是很明显这是一个hack。有人可以帮我提供更优雅的解决方案吗?谢谢


问题答案:

不幸的是,即使WRAP_ROOT_VALUE启用了该功能,您仍然需要额外的逻辑来控制序列化Java集合时生成的根名称(有关详细信息,请参阅此答案)。这给您提供以下选择:

  • 使用Holder类定义根名称
  • 使用地图。
  • 使用自定义 ObjectWriter

以下代码说明了三个不同的选项:

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

输出:

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

使用an ObjectWriter非常方便-只需记住,使用它序列化的所有顶级对象都将具有相同的根名。如果那不是理想的,则使用map或holder类。



 类似资料:
  • 问题内容: 我遇到了一个问题,试图将List作为根节点,但似乎无法获得此信息。让我解释。假设我们有一个类“ TestClass” 现在,在某些实用程序方法中,这就是我要做的 我想以JSON格式获取的输出是 我尝试使用 但是,我似乎仍然做得不好。 现在,我只是创建一个,并编写该代码来实现我要执行的操作,该方法可以正常工作,但显然这是一个hack。有人可以帮我提供更优雅的解决方案吗?谢谢 问题答案:

  • 问题内容: 使用以下代码,我已将列表转换为json,但格式如下: 但我想将其转换为: 以下是我的弹簧控制器: 问题答案: 更改从返回结果给放: 如此; 更新 您可以将结果作为字符串返回,您将获得所需的内容: 返回的字符串是json格式。

  • 我正在调用一个返回JSON的endpoint,它看起来像这样(在Postman中): 此请求返回的Content-Type头是(与通常的 类来自外部库(编写这个endpoint的人)。无论如何,当我试图通过< code > rest template . exchange()调用这个endpoint时,Jackson都无法将这个JSON反序列化为一个有效的< code>Result类。我正在这样做

  • 我如何告诉Jackson忽略JSON名称? 我有以下POJO: 当我有这样的东西: “ABCName”:“foo”,然后杰克逊没有认出它抛出错误。 它期望的是: “abcName”:“foo”。 代码: 输出:{"abcname":"Foo"} 然后我试着用@JsonProperty(“ABCName”)注释ABCName 在我注释并运行代码之后,我得到的是:{“ABCName”:“Foo”,“A

  • 问题内容: 我有一个特定的JSON节点,它对应于导入org.codehaus.jackson.JsonNode,而不是导入org.codehaus.jackson.map.JsonNode。 我想从上述数组的所有JSON节点中删除“ familyName”和“ middleName”。有什么办法可以做到这一点? 问题答案: 我还没有测试过,但是我认为这样可以满足您的需求: 您还可以使用Jackon

  • 有没有办法让Jackson序列化某个流对象(并在之后关闭)?这样地: 使现代化 澄清:我想流式传输内容,而不仅仅是将其序列化到单个String对象。