【问题标题】:Jackson: different XML and JSON formatJackson:不同的 XML 和 JSON 格式
【发布时间】:2015-06-06 03:28:53
【问题描述】:

在我基于 Apache wink 的 REST 项目中,我们使用 Jackson jax-rs 提供程序来处理 JSON 和 XML 内容类型。我们的响应对象包含一个HashMap<String, PropertyObject>。 map 键包含空格,因此不能序列化为 XML 元素名称。 JSON 序列化工作正常。

JSON 格式:

{
    "properties": {
          "a b c":  {   
                            "name": "a b c",
                            "type": "Double",
                            "value": "2.0"
                    },
          "x y z":  {
                            "name": "x y z",
                            "type": "Double",
                            "value": "0.0"
                    }
        }
}

所需的 XML 格式

<rootElement>
    <Property name="a b c" type="double" value="2.0">
    <Property name="x y z" type="double" value="0.0">
</rootElement>

我们如何使用 Jackson jax-rs XML 和 JSON 提供程序来实现这一点。是否可以定义自定义杰克逊序列化程序并扩展 jax-rs 提供程序。请提出一个最好的方法。

【问题讨论】:

  • 您需要包括使用的 POJO,因为没有它们就不可能知道如何到达那里。

标签: java xml json jackson jax-rs


【解决方案1】:

更改 XML 的一种方法是使用 JAXB XmlAdapter。类似的东西

public class PropertyAdapter extends XmlAdapter<PropertyAdapter.AdaptedProperties, 
                                                HashMap<String, PropertyObject>> {
    
    public static class AdaptedProperties {
        public ArrayList<PropertyObject> property = new ArrayList<>();
    }
    
    @Override
    public HashMap<String, PropertyObject> unmarshal(
                        PropertyAdapter.AdaptedProperties list) throws Exception {
        
        HashMap<String, PropertyObject> map = new HashMap<>();
        for (PropertyObject prop: list.property) {
            map.put(prop.getName(), prop);
        }
        return map;
    }

    @Override
    public PropertyAdapter.AdaptedProperties marshal(
                           HashMap<String, PropertyObject> map) throws Exception {
        
        ArrayList<PropertyObject> list = new ArrayList<>(map.values());
        AdaptedProperties props = new AdaptedProperties();
        props.property = list;
        return props;
    }
}

然后只需注释字段/属性

@XmlRootElement
public class DTO {
    
    private HashMap<String, PropertyObject> properties;

    @XmlJavaTypeAdapter(PropertyAdapter.class)
    public HashMap<String, PropertyObject> getProperties() {
        return properties;
    }

    // setter
}

这将是结果。这不是您想要的,但如果没有 &lt;properties&gt; 包装器,我无法弄清楚如何获得它。

<root>
    <properties>
        <property name="a b c" type="Double" value="2.0"/>
        <property name="x y z" type="Double" value="0.0"/>
    </properties>
</root>

您还需要确保的一件事是,当您使用 Jackson 时,您没有使用配置了 JAXB 注释支持的提供程序。如果您使用此提供程序,它将使用XmlAdapter,您将获得一个 JSON 数组,而不是像您目前拥有的对象/映射。假设您使用的是this provider,它有一个JacksonJaxbJsonProvider 和一个普通的JacksonJsonProvider。您要确保只注册后者。


编辑

哦,我忘记补充了,我用来测试的 PropertyObject 类看起来像这样

@XmlRootElement
public class PropertyObject {
    
    private String name;
    
    @XmlAttribute(name = "name")
    public String getName() {
        return name;
    }

    // There are `type` and `value` fields also, with corresponding
    // getters and setters, both using the `@XmlAttribute`
}

更新

假设您确实希望 JAXB 注释支持 Jackson JSON 序列化。您可以做的是配置您自己的ObjectMapper,并且只使用具有JAXB 支持的那一类。你可以看看possible here

【讨论】:

    猜你喜欢
    • 2017-05-30
    • 2014-08-04
    • 2014-11-17
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2017-09-29
    • 1970-01-01
    相关资源
    最近更新 更多