Jackson json 反序列化,忽略来自 json 的根元素 [英] Jackson json deserialization, ignore root element from json

查看:35
本文介绍了Jackson json 反序列化,忽略来自 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") 注释,也不会被发现.

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 注释时解包根标签,否则不要解包.

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 中的 TestRootName.java 中的示例.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);
}

这篇关于Jackson json 反序列化,忽略来自 json 的根元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆