杰克逊:不同的XML和JSON格式 [英] Jackson: different XML and JSON format

查看:145
本文介绍了杰克逊:不同的XML和JSON格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my Apache wink based REST project, we are using Jackson jax-rs providers for handling both JSON and XML content type. Our response object contains a HashMap<String, PropertyObject>. The map key contains whitespaces and hence it can't be serialized as XML element names. JSON serialization works fine.

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提供程序实现这一目标。是否可以定义自定义jackson序列化程序并扩展jax-rs提供程序。请提出最佳方法。

How can we achieve this using Jackson jax-rs XML and JSON providers. Is it possible to define custom jackson serializers and extend jax-rs providers. Please suggest a best possible approach.

推荐答案

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

One way you can change the XML is to use a JAXB XmlAdapter. Something like

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;
    }
}

然后只需注释字段/属性

Then just annotate the field/property

@XmlRootElement
public class DTO {

    private HashMap<String, PropertyObject> properties;

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

    // setter
}

这将是结果。这不完全是你想要的,但我不知道如何在没有< properties> 包装器的情况下获得它。

This will be the result. It's not exactly how you want it, but I can't figure out how to get it without the <properties> wrapper.

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

你需要确定的一件事是,当你使用杰克逊时,你不是使用已配置JAXB批注支持的提供程序。如果您使用此提供程序,它将使用 XmlAdapter ,您将获得一个JSON数组,而不是您目前拥有的对象/地图。假设您正在使用此提供商,它有一个 JacksonJaxbJsonProvider 和普通的 JacksonJsonProvider 。你想确保只注册后者。

One thing you also need to make sure of is that when you are using Jackson, you aren't using the provider that has JAXB annotation support configured. If you use this provider, it will use the XmlAdapter and you will get a JSON array, instead of an object/map like you currently have. Assuming you are using this provider, it has a JacksonJaxbJsonProvider and a plain JacksonJsonProvider. You want to make sure to just register the latter.

哦,我忘了添加我用来测试的 PropertyObject 类看起来像这样

Oh and I forgot to add that the PropertyObject class I used to test looks like this

@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`
}






更新



假设你 想要杰克逊JSON序列化的JAXB注释支持。你可以做的是配置你自己的 ObjectMapper ,只需使用JAXB支持这个类。你可以看到可能在这里


UPDATE

Let's assume you did want the JAXB annotation support for Jackson JSON serialization. What you can do is configure your own ObjectMapper, and just use the one with JAXB support for this one class. You can see how that is possible here

这篇关于杰克逊:不同的XML和JSON格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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