Jackson 生成xml格式文件
Jackson是java应用中流行的操作Json工具库,很快成为Java生态中事实标准,Spring boot默认也使用Jackson。从版本2开始,支持json的同时引入成熟的xml实现。
1. 环境依赖
增加Jackson xml 模块,仅需要一个依赖:
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.9.0</version></dependency>
Gradle版本:
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.0"
1.1 配置Jackson Xml 模块
Jackson通常使用ObjectMapper
实例;如果要使用xml相关操作,则需要使用XmlMapper
类,其是ObjectMapper
类的派生类,两者使用方式几乎一致。
最简单方式定义:
ObjectMapper objectMapper = new XmlMapper();
也可以增加一些通用配置:
JacksonXmlModule xmlModule = new JacksonXmlModule();xmlModule.setDefaultUseWrapper(false);ObjectMapper objectMapper = new XmlMapper(module);
对2.9版本,仅对xml有效的配置包括:
setDefaultUseWrapper– 定义默认情况下是否为未带注释的列表属性使用包装器。即对列表属性生成一个外层元素。setXMLTextElementName– 当处理字符串数据时使用虚拟名称。
1.2 Spring Boot配置
由于Spring Boot默认没有暴露XmlMapper
作为Bean,因为会与ObjectMapper
冲突,XmlMapper
是其子类。但可以使用MappingJackson2XmlHttpMessageConverter
信息转换Bean进行获取。配置示例:
@Componentpublic class MetaConvert implements IMetaConvert{private ObjectMapper xmlMapper;public MetaConvert(MappingJackson2XmlHttpMessageConverter xmlConverter) {xmlMapper = xmlConverter.getObjectMapper();}@Overridepublic String convertMetaToXml(Object metaInfo) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();try {xmlMapper.writeValue(byteArrayOutputStream, metaInfo);} catch (IOException e) {log.error(e.getMessage());throw MetaFileException.of(e.getMessage());}return byteArrayOutputStream.toString();}}
2. 处理xml
Jackson可以很轻松处理Json,利用一些注解进行标识。XmlMapper
是ObjectMapper
的子类,仅为了处理xml,这意味着Api完全相同,可以直接使用。
2.1 写Xml
写Xml使用Jackson提供的多个重载方法writeValue()
。举例,序列化对象至xml可以简单使用writeValueAsString
方法:
String xml = objectMapper.writeValueAsString(input);
其他几个方法:
Writing to a StringWriting to a Byte ArrayWriting to ajava.io.OutputStream– 如:网络连接的流Writing to ajava.io.WriterWriting to ajava.io.File
2.2 读Xml
刚才我们看到Jackson可以很好地处理写操作,它也可以处理读操作,同样利用多个重载方法readValue()
方法。举例,从输入流中读xml生成Java Bean:
MyBean bean = objectMapper.readValue(inputStream, MyBean.class);
其他重载方法有:
Reading from a StringReading from a Byte ArrayReading from ajava.io.InputStream– 如:网络连接的流Reading from ajava.io.ReaderReading from ajava.io.File
3. Jackson 序列化注解
Jackson XML模块支持Jackson提供的用于注释pojo的所有注释。这意味着我们有一组bean和注释,并根据ObjectMapper实例选择是获得XML还是JSON。在构造代码时,这是一个巨大的好处,因为不再担心在表示相同数据的不同bean之间进行转换,从而获得不同的序列化格式。
举例:
@JsonPropertyOrder({"age", "id", "name"})public class Person {@JsonProperty("_id")private String id;private String name;private int age;@JsonIgnoreprivate String note;}
生成json:
{"age":4,"_id":"12345","name":"George"}
xml格式:
<Person><age>4</age><_id>12345</_id><name>George</name></Person>
3.1 针对xml的注解
Jackson Xml 模块增加了对xml特性支持的属性。这些注解用于控制元素(包括根元素)的xml命名空间、本地名称,字段是否被渲染为元素或普通文本,元素内容是否被渲染为CData 包装,集合属性是否使用包装元素等。下面针对常用注解进行分别说明。
@JacksonXmlProperty
@JacksonXmlProperty
可以用在bean的任何字段上,控制渲染元素的一些细节属性。通过该注解可以设置命名控件、本地名称、是否被序列化为元素或属性。举例如下:
public class Person {@JacksonXmlProperty(isAttribute = true, namespace = "urn.stackify.jacksonxml", localName = "_id")private String id;@JacksonXmlProperty(namespace = "urn.stackify.jackson")private String name;private String note;}
输出结果:
<Person xmlns:wstxns1="urn.stackify.jacksonxml" wstxns1:_id="12345"><wstxns2:name xmlns:wstxns2="urn.stackify.jackson">Graham</wstxns2:name><note>Hello</note></Person>
@JacksonXmlRootElement
@JacksonXmlRootElement
与上面提及的注解类似,但作用与整个文档的根元素。可设定命名空间和本地名称,根元素不会作为属性序列化。我们看下面Person
POJO示例:
@JacksonXmlRootElement(namespace = "urn.stackify.jacksonxml", localName = "PersonData")public class Person {private String id;private String name;private String note;}
输出结果:
<PersonData xmlns="urn.stackify.jacksonxml"><id xmlns="">12345</id><name xmlns="">Graham</name><note xmlns="">Hello</note></PersonData>
@JacksonXmlText
我们在看看@JacksonXmlText
注解。其表示属性被渲染为普通文本,无需额外元素包裹。举例:
public class Person {private String id;private String name;@JacksonXmlTextprivate String note;}
输出结果:
<Person><id>12345</id><name>Graham</name>Hello</Person>
当然你要谨慎使用该注解,确保生成xml为有效格式。
@JacksonXmlCData
@JacksonXmlCData
注解表示其内容不被xml解析,一般和@JacksonXmlText
一起使用。请看示例:
public class Person {private String id;@JacksonXmlCDataprivate String name;@JacksonXmlText@JacksonXmlCDataprivate String note;}
输出结果为:
<Person><id>12345</id><name><![CDATA[Graham]]></name><![CDATA[Hello]]></Person>
@JacksonXmlElementWrapper
@JacksonXmlElementWrapper注解覆盖setDefaultUseWrapper的确省设置。其能够让集合属性决定是否使用包装元素,并且也可以控制包装元素的本地名称和命名空间。
使用包装元素则增加额外元素包括所有集合元素,反之,直接列出所有集合元素:
class Wrapper {@JacksonXmlElementWrapper(localName = "list")private List names;}
输出结果:
<Wrapper><list><names>John</names><names>Paul</names><names>George</names><names>Ringo</names></list></Wrapper>
如果设置不用包装元素:
@JacksonXmlElementWrapper(useWrapping = false)
输出结果:
<Wrapper><names>John</names><names>Paul</names><names>George</names><names>Ringo</names></Wrapper>
4. 总结
Jackson可以灵活地采用相同方式处理JSON和XML数据,Jackson Xml 模块还增加xml特有的处理方式和注解。
如果觉得《Jackson 生成xml格式文件》对你有帮助,请点赞、收藏,并留下你的观点哦!