java 如何在 Jackson 生成的 JSON 中将 List 包装为顶级元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16022795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to wrap a List as top level element in JSON generated by Hymanson
提问by Seagull
I am running into a problem where I am trying to include a List as the root node, but I can't seem to be able to get this. Let me explain. Let's say we have a class "TestClass"
我遇到了一个问题,我试图将一个 List 作为根节点包含在内,但我似乎无法得到这个。让我解释。假设我们有一个类“TestClass”
class TestClass{
String propertyA;
}
Now, in some utility method this is what I do
现在,在某些实用方法中,这就是我所做的
String utilityMethod(){
List<TestClass> list = someService.getList();
new ObjectMapper().writeValueAsString(list);
}
The output I am trying to get in JSON is
我试图在 JSON 中获得的输出是
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
I have tried to use
我试过用
objMapper.getSerializationConfig().set(Feature.WRAP_ROOT_VALUE, true);
But, I still don't seem to get it right.
但是,我似乎仍然没有做对。
Right now, I am just creating a Map < String,TestClass > and I write that to achieve what I am trying to do, which works but clearly this is a hack. Could someone please help me with a more elegant solution? Thanks
现在,我只是在创建一个 Map < String,TestClass > 并且我编写它来实现我想要做的事情,这可行,但显然这是一个黑客。有人可以帮我提供更优雅的解决方案吗?谢谢
回答by Perception
Unfortunately, even with the WRAP_ROOT_VALUE
feature enabled you still need extra logic to control the root name generated when serializing a Java collection (see this answerfor details why). Which leaves you with the options of:
不幸的是,即使WRAP_ROOT_VALUE
启用了该功能,您仍然需要额外的逻辑来控制序列化 Java 集合时生成的根名称(有关详细信息,请参阅此答案)。这让您有以下选择:
- using a holder class to define the root name
- using a map.
- using a custom
ObjectWriter
- 使用持有者类来定义根名称
- 使用地图。
- 使用自定义
ObjectWriter
Here is some code illustrating the three different options:
下面是一些说明三个不同选项的代码:
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()));
}
}
Output:
输出:
{"ArrayList":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ArrayList":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"} "}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA ":"someOtherPropertyValue"}]}
Using an ObjectWriter
is very convenient - just bare in mind that all top level objects serialized with it will have the same root name. If thats not desirable then use a map or holder class instead.
使用 anObjectWriter
非常方便 - 请记住,使用它序列化的所有顶级对象都将具有相同的根名称。如果那是不可取的,那么请改用 map 或 holder 类。
回答by searlea
I'd expect the basic idea to be something like:
我希望基本的想法是这样的:
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);
}