【问题标题】:Jackson serializer wrapping lists by default?默认情况下杰克逊序列化程序包装列表?
【发布时间】:2017-09-15 09:09:51
【问题描述】:

我正在使用spring 和RestTemplate 到postForEntity(req, rsp) xml 到网络服务。

@Bean
public Jackson2ObjectMapperBuilderCustomizer initJackson() {
    return (builder) -> builder.modules(new JaxbAnnotationModule());
}

java bean 是使用xsdtojava 从xsd 文件自动生成的。因此我无法修改生成的类!

问题:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Generated
public class MyRequest {
    @XmlElement(required = true)
    private SubReq subs;

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType
    public static class SubReq {
        private List<String> list;
    }
}

结果:&lt;list&gt; 元素包含额外的嵌套 &lt;list&gt; 元素。但为什么?又该如何预防?

当前:

<MyRequest>
    <SubReq>
        <list>  
            <list>val1</list>
            <list>val2</list>
        </list>
    </SubReq>
</MyRequest>

我的目标:

<MyRequest>
    <SubReq>
        <list>val1</list>
        <list>val2</list>
    </SubReq>
</MyRequest>

如何配置杰克逊不将列表包装在里面?

MyRequest 元素是从以下位置自动生成的:

<xs:schema>
    <xs:element name="MyRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="SubReq">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="list" minOccurs="0" maxOccurs="unbounded">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string" />
                                </xs:simpleType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    ...
</xs:schema>

【问题讨论】:

  • 你试过@JsonUnwrapped 了吗?
  • 如前所述,我无法修改自动生成的 java 类。因此,我无法添加任何自定义注释。我必须以某种方式添加一个全局配置来解开任何List 或Map。
  • ..也不能修改objectmapper/deserializer属性?
  • Objectmapper 在我的控制之下。那将是可能的。或者更好的是让我们说builder,例如,我添加注册JaxbAnnotationModule 显式告诉杰克逊利用JAXB 属性。

标签: java json xml spring jackson


【解决方案1】:

我通过使用 defaultUseWrapper(false) 全局禁用 unwrapper 解决了这个问题:

@Bean
public Jackson2ObjectMapperBuilderCustomizer initJackson() {
    return (builder) -> builder.modules(new JaxbAnnotationModule())
                    .defaultUseWrapper(false);
}

【讨论】:

    【解决方案2】:

    您可以为此将DeserializationFeature.UNWRAP_ROOT_VALUE 设置为true:

    objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
    objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
    

    此属性的默认值为true。

    这是在一个限制下,我最好在生成代码时用@JsonUnwrapped注释这些字段。

    【讨论】:

    • 嗯,我尝试设置 UNWRAP_SINGLE_VALUE_ARRAYS 和 UNWRAP_ROOT_VALUE 但这没有帮助。列表仍然是嵌套的。好吧,如前所述,我无法将 @JsonUnwrapped 添加到自动生成的类中......
    • 在这种情况下听起来像是一个可能的错误,这是否也会发生在未声明为内部类但包含类似模型的类上?
    • 所以但问题是:自动生成的 java 类层次结构错误,还是反序列化功能?在上面添加了xsd 源代码。
    • @membersound 如果UNWRAP.. 功能适用于非内部类的类,这肯定是一个错误。虽然还没有测试,但我的第一个想法是我已经看到普通的 POJO 也可以与 @JsonUnwrapped 一起用作内部类。在这种情况下,事情可能在反序列化级别搞砸了。
    猜你喜欢
    • 2018-07-21
    • 1970-01-01
    • 2013-09-12
    • 2013-05-20
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多