TechBits | 如何返回Xml格式的响应
前言
公司最近要求对接,返回响应格式为Xml
类型的数据。我们最近经常接触的请求就是Json
格式的数据,它体量小、传输速度快、支持的工具多种多样。而Xml
已经是很久之类的格式了。不过,xml
格式也需要了解一下,后面也可能出现更多的新的格式,多了解一些就自己的进度也就越快。那么,长话短说,开始我们今天的学习之旅吧。😀
常见的XML处理方式以及相关的库
-
DOM (Document Object Model) :
- Java内置支持的XML处理方式之一。
- 使用DOM,XML文档被解析为一个树形结构,可以通过操作节点来访问和修改XML内容。
- Java标准库提供了
javax.xml.parsers.DocumentBuilder
用于创建DOM树。
-
SAX (Simple API for XML) :
- 另一种Java内置的XML处理方式。
- SAX是一种事件驱动的处理方式,逐行解析XML文档并触发事件处理程序。
- 使用SAX时,不需要构建整个XML树,适用于大型XML文档或需要一次处理一部分的情况。
- Java标准库提供了
org.xml.sax.XMLReader
用于SAX处理。
-
JAXB (Java Architecture for XML Binding) :
- JAXB是Java的一个标准,用于将Java对象与XML之间进行相互转换。
- 使用JAXB,您可以通过注解标记Java类,然后将其自动序列化为XML,或者将XML反序列化为Java对象。
- JAXB提供了
javax.xml.bind
包,可以用于创建JAXB上下文并进行数据绑定。
-
JDOM:
- JDOM是一个用于处理XML的开源Java库,它提供了更友好和易用的API。
- JDOM允许您以更直观的方式操作XML文档,而不需要处理底层的DOM或SAX事件。
- 您可以使用JDOM来创建、解析和操作XML文档。
-
DOM4J:
- DOM4J是另一个流行的用于处理XML的开源Java库。
- 它提供了一种灵活而高性能的方式来操作XML文档。
- DOM4J支持XPath查询、XML写入和许多其他功能。
-
StAX (Streaming API for XML) :
- StAX是一种基于流的XML处理方式,允许您按顺序读取或写入XML数据。
- StAX提供了
javax.xml.stream
包,包括XMLStreamReader
和XMLStreamWriter
用于处理XML流。
种类多,我们就选择最常使用的JAXB (Java Architecture for XML Binding) 。
实战
Springboot项目接口请求返回Xml格式响应
引入POM文件
javax.xml.bind
jaxb-api
2.3.1
org.glassfish.jaxb
jaxb-runtime
2.3.1
com.fasterxml.jackson.dataformat
jackson-dataformat-xml
编写实体类
@XmlRootElement
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator") //uuid自增
@Column(name = "id", columnDefinition = "BINARY(16)" ,nullable = false)
private String id;
@XmlElement
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@XmlElement
public Gen getGen() {
return gen;
}
public void setGen(Gen gen) {
this.gen = gen;
}
@Column(name = "name")
private String name;
@Column(name = "age")
private int age;
@Enumerated(EnumType.STRING)
@Column(name = "gen")
private Gen gen;
}
注意: @XmlElement 标签 会与 lombok 的@Data 和 @Setter 、@Getter 注解发生冲突,大致原因就是@Data产生的注解会使@JAXB认为产生重复的名称。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class EmployeeList {
@XmlElementWrapper(name = "employees")
@XmlElement(name = "employee")
private List employees;
// Getter and setter for employees list
public EmployeeList() {
this.employees = new ArrayList();
}
public EmployeeList(List employees) {
this.employees = employees;
}
public List getEmployees() {
return employees;
}
public void setEmployees(List employees) {
this.employees = employees;
}
}
注:如果想返回list集合类型的数据,则需要使用创建一个专门转换list的对象。不然,jaxb 无法转换具有超类的对象。并且,需要为其对象添加无参构造函数,不然也会出现错误。
配置Xml转换器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List clazz) throws JAXBException {
JAXBContext context = contextCache.get(clazz);
if (context == null) {
context = JAXBContext.newInstance(clazz);
contextCache.put(clazz, context);
}
return context;
}
public static void main(String[] args) throws JAXBException {
// 示例使用
Class employeeClass = Employee.class;
// 从缓存获取JAXB上下文
JAXBContext context = JAXBContextCache.getContext(employeeClass);
// 使用上下文进行序列化或反序列化操作
// ...
}
}
处理集合:JAXB还支持处理集合,例如List
或Set
,可以将多个对象序列化为XML元素的列表,或者将XML元素列表反序列化为Java集合。
自定义映射:如果需要更复杂的映射,可以使用JAXB提供的自定义绑定选项,或者使用外部绑定文件(例如XML绑定语言文件)来自定义映射规则。
我们有以下XML文档表示一个Book对象
Java Programming
John Doe
我们的Book类如下
@XmlRootElement
public class Book {
private String title;
private String author;
// 省略构造函数和访问器方法
}
假设我们想要自定义映射规则,以将元素映射到
title
属性,将元素映射到
author
属性之外,还要将元素映射到
year
属性。我们可以使用XML绑定语言文件来实现这个自定义映射:
使用xjc
工具来生成自定义映射的Java类。运行以下命令:
xjc -d src -b customBindings.xml your-schema.xsd
这将生成与自定义映射规则匹配的Book
类,包括title
、author
和year
属性。现在,可以使用新生成的Book
类来进行序列化和反序列化,JAXB将按照自定义映射规则处理XML数据