如何在代码中为JACKSON提供namespace-mapper? [英] How to provide JACKSON with the namespace-mapper in the code?

查看:120
本文介绍了如何在代码中为JACKSON提供namespace-mapper?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试序列化JAXB生成的类。使用Jettison,我可以创建一个哈希映射,将XML名称空间映射到任何JSON前缀。使用Jettison,我也可以在序列化中获得区分大小写。使用JACKSON,它都是小写的。所以,似乎Jettison能够更好地理解 XMLRootElement(name = ...)

I am trying to serialize a JAXB generated class. With Jettison, I am able to create a hash-map mapping the XML namespaces to any JSON prefix. With Jettison, I also get the case sensitivity right in the serialization. With JACKSON, it is all lower case. So, it seems that Jettison is able to understand XMLRootElement(name=…) much better.

我如何让JACKSON更好地理解JAXB注释,比如 XMLRootElement

How do I make JACKSON better understand JAXB annotations like XMLRootElement?

如何为JACKSON提供XML→ JSON命名空间映射器?

How do I provide JACKSON with a XML→JSON namespace mapper?

推荐答案

注意:我是 EclipseLink JAXB(MOXy) 领导和 JAXB(JSR-222)专家组。

EclipseLink MOXy是一个JAXB( JSR-222)兼容的实现。在EclipseLink 2.4.0中,我们引入了JSON绑定。由于MOXy是一个JAXB实现,您会发现MOXy产生的JSON输出与基于相同元数据的XML输出非常一致。我将在下面举例说明。

EclipseLink MOXy is a JAXB (JSR-222) compliant implementation. In EclipseLink 2.4.0 we introduced JSON-binding. Since MOXy is a JAXB implementation you will find the JSON output MOXy produces will be very consistent with XML output based on the same metadata. I will demonstrate below with an example.

DOMAIN MODEL

以下是我将用于此答案的域模型。有关在JAXB模型中指定命名空间信息的详细信息,请参阅: http:// blog。 bdoughan.com/2010/08/jaxb-namespaces.html

Below is the domain model I will use for this answer. For more information on specifying namespace information in a JAXB model see: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html

package-info

package-info

@XmlSchema(
        namespace="http://www.example.com/A",
        elementFormDefault=XmlNsForm.QUALIFIED,
        xmlns={
                @XmlNs(prefix="a",namespaceURI = "http://www.example.com/A"),
                @XmlNs(prefix="b",namespaceURI = "http://www.example.com/B")
        }
)
package forum13214306;

import javax.xml.bind.annotation.*;

客户

Customer

package forum13214306;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    String firstName;

    @XmlElement(namespace="http://www.example.com/B")
    String lastName;

}






XML处理

以下是域模型如何与XML表示形式对应的示例。

Below is an example of how the domain model corresponds to an XML representation.

演示

Demo

package forum13214306;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum13214306/input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

输入.xml /输出

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<a:customer xmlns:b="http://www.example.com/B" xmlns:a="http://www.example.com/A">
   <a:firstName>Jane</a:firstName>
   <b:lastName>Doe</b:lastName>
</a:customer>






JSON处理 - 没有名字

命名空间不是JSON概念所以如果可以避免这种情况,我建议不要模拟它们。下面我将证明MOXy不需要它们。请注意,完全相同的域模型和 JAXBContext 用于带有名称空间的XML文档。

Namespaces aren't a JSON concept so I would recommend not simulating them if you can avoid this. Below I'll demonstrate that MOXy doesn't need them. Note the exact same domain model and JAXBContext is used here that was used for the XML document with namespaces.

jaxb.properties

jaxb.properties

要将MOXy指定为JSON提供程序,您需要包含一个名为 jaxb.properties 与您的域模型在同一个包中,并带有以下条目(请参阅: http://blog.bdoughan.com/search/label/jaxb.properties )。

To specify MOXy as your JSON provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/search/label/jaxb.properties).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

Demo

要启用JSON绑定 MEDIA_TYPE 属性需要在 Marshaller Unmarshaller 上启用。

To enable JSON binding the MEDIA_TYPE property needs to be enable on the Marshaller and Unmarshaller.

package forum13214306;

import java.io.File;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
        File json = new File("src/forum13214306/input.json");
        Customer customer = (Customer) unmarshaller.unmarshal(json);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.marshal(customer, System.out);
    }

}

输入.json /输出

input.json/Output

以下是运行演示代码的输入和输出。请注意JSON文档中没有模拟名称空间信息。

Below is the input to and output from running the demo code. Note how there is no simulated namespace information in the JSON document.

{
   "customer" : {
      "firstName" : "Jane",
      "lastName" : "Doe"
   }
}






JSON处理 - 使用模拟的名字

演示

Demo

如果您真的想在JSON文档中模拟名称空间,可以利用 NAMESPACE_PREFIX_MAPPER 属性 Marshaller Unmarshaller 这样做。

If you really want to simulate namespaces in your JSON document you can leverage the NAMESPACE_PREFIX_MAPPER property on the Marshaller and Unmarshaller to do so.

package forum13214306;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Map<String, String> namespaceToPrefixMap = new HashMap<String, String>(2);
        namespaceToPrefixMap.put("http://www.example.com/A", "a");
        namespaceToPrefixMap.put("http://www.example.com/B", "b");

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
        unmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaceToPrefixMap);
        File json = new File("src/forum13214306/input.json");
        Customer customer = (Customer) unmarshaller.unmarshal(json);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaceToPrefixMap);
        marshaller.marshal(customer, System.out);
    }

}

input.json /输出

{
   "a.customer" : {
      "a.firstName" : "Jane",
      "b.lastName" : "Doe"
   }
}






更多信息

  • http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html
  • http://blog.bdoughan.com/2012/05/moxy-as-your-jax-rs-json-provider.html

这篇关于如何在代码中为JACKSON提供namespace-mapper?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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