简体   繁体   English

使用Jackson API和JAXB Annotations将JSON转换为XML,反之亦然

[英]Converting JSON to XML and vice versa using Jackson API and JAXB Annotations

I'm trying to write a code which can take either XML or JSON input and output JSON or XML respectively. 我正在尝试编写一个代码,它可以分别使用XML或JSON输入并输出JSON或XML。 Ie, if I give XML it should give back JSON, and if I give JSON it should give XML output. 即,如果我给XML它应该给回JSON,如果我给JSON它应该给出XML输出。

I was told this is possible using Jackson API and JAXB Annotations. 我被告知使用Jackson API和JAXB Annotations可以实现这一点。 Can anyone help me out with this? 任何人都可以帮我解决这个问题吗?

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group. 注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB(JSR-222)专家组的成员。

Below is an example of how you can use MOXy's JSON-binding to support this use case. 下面是一个如何使用MOXy的JSON绑定来支持这个用例的示例。

JAVA MODEL JAVA模型

Below is an example domain model annotated with JAXB metadata. 下面是使用JAXB元数据注释的示例域模型。 The same metadata will be used for both the object-to-XML and object-to-JSON conversions. 相同的元数据将用于对象到XML和对象到JSON的转换。

Customer 顾客

import java.util.List;
import javax.xml.bind.annotation.*;

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

    private int id;

    private String firstName;

    @XmlElement(nillable=true)
    private String lastName;

    private List<PhoneNumber> phoneNumbers;

}

PhoneNumber 电话号码

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {

    @XmlAttribute
    private String type;

    @XmlValue
    private String number;

}

XML INPUT XML INPUT

Below is the XML input that we will use. 下面是我们将使用的XML输入。 Note how the xsi:nil attribute is used on the lastName element to indicate a null value. 请注意如何在lastName元素上使用xsi:nil属性来指示null值。 Also note how the phoneNumbers element has a type attribute. 另请注意phoneNumbers元素如何具有type属性。

<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <id>123</id>
   <firstName>Jane</firstName>
   <lastName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
   <phoneNumbers type="work">555-1111</phoneNumbers>
</customer>

DEMO CODE 演示代码

jaxb.properties jaxb.properties

To specify MOXy as your JAXB 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/2011/05/specifying-eclipselink-moxy-as-your.html ): 要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含一个名为jaxb.properties的文件,并带有以下条目(请参阅: http//blog.bdoughan.com/2011/05/specifying-eclipselink- moxy-as-your.html ):

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

Demo 演示

The following demo code will convert the XML to the domain model and then back to JSON. 以下演示代码将XML转换为域模型,然后再转换回JSON。

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

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/forum14734741/input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

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

}

JSON OUTPUT JSON OUTPUT

Note how the null value for the lastName key is represented as proper JSON. 请注意lastName键的null值如何表示为正确的JSON。 Also note how the type key doesn't contain any special indicator corresponding to it being an XML attribute in the XML representation. 还要注意type键如何不包含与XML表示中的XML属性相对应的任何特殊指示符。

{
   "id" : 123,
   "firstName" : "Jane",
   "lastName" : null,
   "phoneNumbers" : [ {
      "type" : "work",
      "value" : "555-1111"
   } ]
}

Sure, but don't think of it as converting between XML and JSON -- this is pretty much the wrong thing to do, causing compatibility issues -- but that of converting Java Objects (POJOs) to/from JSON and XML. 当然,但不要把它当作XML和JSON之间的转换 - 这几乎是错误的,导致兼容性问题 - 但是将Java对象(PO​​JO)转换为JSON和XML。 You can use one or two tools for this: one common combination is to use Jackson for JSON, and JAXB for XML, to use their respective strengths. 您可以使用一个或两个工具:一个常见的组合是使用Jackson for JSON,而JAXB for XML,使用它们各自的优势。

It is also possible to use a single tool; 也可以使用单一工具; Blaise explained how JAXB implementations can help. Blaise解释了JAXB实现如何提供帮助。 Similarly, you can use Jackson for both: for XML part you need to use Jackson XML module . 同样,您可以将Jackson用于两者:对于XML部分,您需要使用Jackson XML模块 With Jackson, you can use Jackson's own annotations (prefered), or JAXB annotations for compatibility; 使用Jackson,您可以使用Jackson自己的注释(首选)或JAXB注释来实现兼容性; both work for XML and JSON use cases. 两者都适用于XML和JSON用例。

Use of XML module with Jackson does not differ a lot from default JSON processing, except that you will need XmlMapper sub-class of ObjectMapper . 与Jackson一起使用XML模块与默认的JSON处理没有太大的区别,除了你需要ObjectMapper XmlMapper子类。 If using this from JAX-RS (like Jersey), you can use Jackson JAX-RS XML provider . 如果使用JAX-RS(如Jersey),可以使用Jackson JAX-RS XML提供程序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM