Jackson反序列化,忽略json中的根元素

7bsow1i6  于 2023-08-08  发布在  其他
关注(0)|答案(5)|浏览(118)

如何从json忽略parent标记??
这是我的json

String str = "{\"parent\": {\"a\":{\"id\": 10, \"name\":\"Foo\"}}}";

字符串
下面是要从jsonMap的类。

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 {

@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所给出的解答注解::

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


工作完成!!
另一个打嗝与Jackson的方式反序列化:(
如果已配置“DeserializationConfig.Feature.UNWRAP_ROOT_VALUE”,则它将展开所有JSON,即使我类没有使用@JsonRootName(value =“rootTagInJson”)进行注解,也不会被破坏。
我只想在类用@JsonRootName注解时才打开根标记,否则不要打开。
因此,下面是unwrap root标签的用例。

###########################################################
     Unwrap only if the class is annotated with @JsonRootName.
  ############################################################


我在Jackson源代码的ObjectMapper中做了一个小的改动,创建了一个新版本的jar。1.将此方法放在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.

bwntbbo3

bwntbbo31#

https://github.com/FasterXML/jackson-databind中的TestRootName.java中提取的一个例子可能会给予一个更好的方法来做到这一点。具体使用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);
}

字符串

irtuqstp

irtuqstp2#

我在Spring中开发一个RESTful应用程序时也遇到过类似的问题。我必须支持一个非常异构的API,其中一些有根元素,另一些没有。我找不到比实时配置此属性更好的解决方案。非常遗憾的是,Jackson中没有对每个类的根元素展开的支持。不管怎样,有人可能会发现这很有帮助。

@Component
public class ObjectMapper extends com.fasterxml.jackson.databind.ObjectMapper {
    private void autoconfigureFeatures(JavaType javaType) {
        Annotation rootAnnotation = javaType.getRawClass().getAnnotation(JsonRootName.class);
        this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, rootAnnotation != null);
    }

    @Override
    protected Object _readMapAndClose(JsonParser jsonParser, JavaType javaType) throws IOException, JsonParseException, JsonMappingException {
        autoconfigureFeatures(javaType);
        return super._readMapAndClose(jsonParser, javaType);
    }

}

字符串

eqzww0vc

eqzww0vc3#

很简单:
创建对象Map器的示例并启用 Package 和解 Package 根值

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

字符串
@JsonRootName("yourname")注解添加到DTO

@JsonRootName("root")
public class YourDto {
    // ...
}

epggiuax

epggiuax4#

作为更新Seagabond的帖子,如果你想在写参数值时有同样的效果,你可以覆盖额外的写方法。

@Component
public class ObjectMapper extends com.fasterxml.jackson.databind.ObjectMapper {
    private void autoconfigureFeatures(Object value) {
        JavaType javaType = _typeFactory.constructType(value.getClass());
        autoconfigureFeatures(javaType);
    }
    private void autoconfigureFeatures(JavaType javaType) {
        Annotation rootAnnotation = javaType.getRawClass().getAnnotation(JsonRootName.class);
        this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, rootAnnotation != null);
    }

    @Override
    public void writeValue(DataOutput out, Object value) throws IOException {
        autoconfigureFeatures(value);
        super.writeValue(out, value);
    }

    @Override
    public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException, JsonMappingException {
        autoconfigureFeatures(value);
        super.writeValue(w, value);
    }

    @Override
    public byte[] writeValueAsBytes(Object value) throws JsonProcessingException {
        autoconfigureFeatures(value);
        return super.writeValueAsBytes(value);
    }

    @Override
    public String writeValueAsString(Object value) throws JsonProcessingException {
        autoconfigureFeatures(value);
        return super.writeValueAsString(value);
    }

    @Override
    protected Object _readMapAndClose(JsonParser jsonParser, JavaType javaType) throws IOException, JsonParseException, JsonMappingException {
        autoconfigureFeatures(javaType);
        return super._readMapAndClose(jsonParser, javaType);
    }

}

字符串

vwoqyblh

vwoqyblh5#

我也面临着这种类型的问题。我在配置类中添加了下面的代码行,在这里我定义了RestTemplate及其MessageConverters的配置。
第一个月
基本上,这个配置将帮助Mapper识别所提供的类是否注解了'@ JsonRootName',如果不是,则不需要搜索root。希望它能帮助到你和其他人。

相关问题