杰克逊json反序列化,忽略了json的根元素 [英] Jackson json deserialization, ignore root element from json
问题描述
如何忽略json中的父标记?
How to ignore parent tag from json??
这是我的json
String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}";
这是从json映射的类。
And here is the class to be mapped from json.
public class RootWrapper {
private List<Foo> foos;
public List<Foo> getFoos() {
return foos;
}
@JsonProperty("a")
public void setFoos(List<Foo> foos) {
this.foos = foos;
}
}
这是测试
公共类JacksonTest {
Here is the test public class JacksonTest {
@Test
public void wrapRootValue() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}";
RootWrapper root = mapper.readValue(str, RootWrapper.class);
Assert.assertNotNull(root);
}
我收到错误::
org.codehaus.jackson.map.JsonMappingException: Root name 'parent' does not match expected ('RootWrapper') for type [simple type, class MavenProjectGroup.mavenProjectArtifact.RootWrapper]
我找到了Jackson注释给出的解决方案::
I found the solution given by Jackson annotation::
(a) Annotate you class as below
@JsonRootName(value = "parent")
public class RootWrapper {
(b) It will only work if and only if ObjectMapper is asked to wrap.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
工作完成!!
另一次打嗝用杰克逊的反序列化方法:(
Another hiccup with Jackson way of Deserialization :(
如果'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE配置',它解包所有的jsons,尽管我的类没有用@JsonRootName注释(value = rootTagInJson),不是weired。
if 'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE configured', it unwrap all jsons, eventhough my class in not annotated with @JsonRootName(value = "rootTagInJson"), isn't weired.
我只想在用@JsonRootName注释类的情况下解包root标签,否则不要解包。
I want to unwrap root tag only if the class is annotated with @JsonRootName otherwise, don't unwrap.
以下是解包根标签的用例。
So below is the usecase for unwrap root tag.
###########################################################
Unwrap only if the class is annotated with @JsonRootName.
############################################################
我对Jackson源代码的ObjectMapper进行了一些小改动,并创建了一个新版本的jar。
1.将此方法放在ObjectMapper中
I did a small change in ObjectMapper of Jackson source code and created a new version of jar. 1. Place this method in ObjectMapper
// Ash:: Wrap json if the class being deserialized, are annotated
// with @JsonRootName else do not wrap.
private boolean hasJsonRootName(JavaType valueType) {
if (valueType.getRawClass() == null)
return false;
Annotation rootAnnotation = valueType.getRawClass().getAnnotation(JsonRootName.class);
return rootAnnotation != null;
}
2. Edit ObjectMapper method ::
Replace
cfg.isEnabled(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE)
with
hasJsonRootName(valueType)
3. Build your jar file and use it.
推荐答案
https://github.com/FasterXML/jackson-databind 可能会提供更好的方法。具体使用withRootName():
An example taken from TestRootName.java in https://github.com/FasterXML/jackson-databind may give a better way of doing this. Specifically using withRootName(""):
private ObjectMapper rootMapper()
{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
return mapper;
}
public void testRootUsingExplicitConfig() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer().withRootName("wrapper");
String json = writer.writeValueAsString(new Bean());
assertEquals("{\"wrapper\":{\"a\":3}}", json);
ObjectReader reader = mapper.reader(Bean.class).withRootName("wrapper");
Bean bean = reader.readValue(json);
assertNotNull(bean);
// also: verify that we can override SerializationFeature as well:
ObjectMapper wrapping = rootMapper();
json = wrapping.writer().withRootName("something").writeValueAsString(new Bean());
assertEquals("{\"something\":{\"a\":3}}", json);
json = wrapping.writer().withRootName("").writeValueAsString(new Bean());
assertEquals("{\"a\":3}", json);
bean = wrapping.reader(Bean.class).withRootName("").readValue(json);
assertNotNull(bean);
}
这篇关于杰克逊json反序列化,忽略了json的根元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!