TechBits | 如何返回Xml格式的响应

2023年 9月 3日 33.4k 0

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包,包括XMLStreamReaderXMLStreamWriter用于处理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还支持处理集合,例如ListSet,可以将多个对象序列化为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类,包括titleauthoryear属性。现在,可以使用新生成的Book类来进行序列化和反序列化,JAXB将按照自定义映射规则处理XML数据

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论