欢迎大家来到IT世界,在知识的湖畔探索吧!
下一篇文章:JavaBean 和 XML 相互转换(二)
在我们对接第三方系统时,经常会遇到第三方系统的报文采用 XML 格式,这是就需要将 JavaBean 和 XML 相互转换。
转换工具
在本示例中 JavaBean 和 XML 相互转换的工具采用 Hutool 提供的 JAXBUtil,所以在使用需要引入 Hutool 依赖,如下示例:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.10</version> </dependency>
欢迎大家来到IT世界,在知识的湖畔探索吧!
JAXBUtil 工具其实是对 javax.xml.bind.JAXBContext 进行了包装
下面通过一些简单示例,介绍 JavaBean 和 XML 相互转换常用到的一些注解,在正式开始介绍之前,先定义一些用于转换的 JavaBean,如下所示:
- 学校类:其包括基本类型字段和集合字段
欢迎大家来到IT世界,在知识的湖畔探索吧!/** * 学校 */ @Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) public class School { /** * 学校名称 */ private String name; /** * 学校联系方式 */ private String phone; /** * 学校地址 */ private String address; /** * 班级 */ private List<ClassInfo> classes; }
- 班级类:其包括基本类型字段和集合字段
/** * 班级 */ @Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) public class ClassInfo { /** * 班级编号 */ private String classNo; /** * 班主任 */ private String teacher; /** * 学生 */ private List<Student> students; }
- 学生类:只包括基本类型字段
欢迎大家来到IT世界,在知识的湖畔探索吧!/** * 学生 */ @Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) public class Student { /** * 学号 */ private String no; /** * 学生姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 家庭地址 */ private String address; }
@XmlRootElement
标注位置 |
类 |
是否必须 |
必须 |
注解作用 |
默认是将当前简单类名作为 XML 的 root 标签,如果设置该注解 name 属性,那么 name 属性值作为 root 标签 |
测试代码:只需关注只需结果 root 标签差异
public class XmlBeanMapperTest { /** * 测试 {@link XmlRootElement} 注解 */ @Test public void testXmlRootElement() { Student student = new Student("1001", "张三", 25, "北京市长安街 001 号"); Console.log(JAXBUtil.beanToXml(student)); } }
- 未设置 name 属性
@Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) @XmlRootElement public class Student { // 省略属性 }
执行结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <address>北京市长安街 001 号</address> <age>25</age> <name>张三</name> <no>1001</no> </student>
- 设置 name 属性为 STDENT
@Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) @XmlRootElement(name = "STUDENT") public class Student { // 省略属性 }
执行结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <STUDENT> <address>北京市长安街 001 号</address> <age>25</age> <name>张三</name> <no>1001</no> </STUDENT>
@XmlType
标注位置 |
类 |
是否必须 |
非必须 |
注解作用 |
主要使用其 propOrder 属性,用于对 XML 元素排序,如果设置了 propOrder 属性,那么属性的值要包括所有的待转换的字段 |
@Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) @XmlRootElement @XmlType(propOrder = {"no", "age", "name", "address"}) public class Student { // 省略属性 }
测试代码:
public class XmlBeanMapperTest { /** * 测试 {@link XmlType} 注解 */ @Test public void testXmlType() { Student student = new Student("1001", "张三", 25, "北京市长安街 001 号"); Console.log(JAXBUtil.beanToXml(student)); } }
执行结果:
// 未添加 @XmlType 注解前 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <address>北京市长安街 001 号</address> <age>25</age> <name>张三</name> <no>1001</no> </student> // 添加后,按照指定的顺序排序 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <no>1001</no> <age>25</age> <name>张三</name> <address>北京市长安街 001 号</address> </student>
@XmlAccessorType
标注位置 |
类 |
是否必须 |
非必须 |
注解作用 |
用于控制 JavaBean 和 XML 转换字段和元素之间的映射,包括如下四种控制类型:
|
注意:当使用 Lombok 中 @Data 注解时,若使用 PROPERTY 或 PUBLIC_MEMBER 类型时会出现异常,如果继续使用 @Data 那么就需要使用 FIELD 或 NONE 类型。
对上面公共的学生类做些修改,详见 Student 类中的注释:
//@Data 注释 Lombok @Data 注解,不自动生成 Getter/Setter 方法等 @ToString @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) @XmlRootElement @XmlAccessorType // 根据下面测试的场景,设置对应的值 public class Student { /** * 学号:有 Getter/Setter 方法(通过 Lombok @Getter/@Setter 注解, * 或手动编写 Getter/Setter 方法) */ @Getter @Setter private String no; /** * 学生姓名:将原 private 修饰改为 public 修饰,也就是通过类实例就可以访问该变量 */ public String name; /** * 年龄:使用 @XmlElement 注解,现在可以先了解该注解是用于类属性和 XML 标签映射, * 后面详解 */ @XmlElement private Integer age; /** * 家庭地址:private 修饰的变量没有 Getter/Setter 方法 */ private String address; }
测试类:
public class XmlBeanMapperTest { private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + "<student>\n" + " <address>北京市长安街 001 号</address>\n" + " <age>25</age>\n" + " <name>张三</name>\n" + " <no>1001</no>\n" + "</student>"; /** * 测试 {@link XmlAccessorType} 注解 */ @Test public void testXmlAccessorType() { Student student = new Student("1001", "张三", 25, "北京市长安街 001 号"); Console.log(JAXBUtil.beanToXml(student)); Console.log(JAXBUtil.xmlToBean(XML, Student.class)); } }
- PROPERTY
运行测试类,执行结果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <age>25</age> <no>1001</no> </student> Student(no=1001, name=null, age=25, address=null)
可以看到当注解 @XmlAccessorType value=PROPERTY 时, JavaBean 和 XML 相互映射,只有有 Getter/Setter 方法或标注 @XmlElement 注解的属性生效。
- FIELD
运行测试类,执行结果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <no>1001</no> <name>张三</name> <age>25</age> <address>北京市长安街 001 号</address> </student> Student(no=1001, name=张三, age=25, address=北京市长安街 001 号)
可以看到当注解 @XmlAccessorType value=FIELD 时, JavaBean 和 XML 相互映射,学生类中的字段都生效
- PUBLIC_MEMBER
运行测试类,执行结果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <name>张三</name> <age>25</age> <no>1001</no> </student> Student(no=1001, name=张三, age=25, address=null)
可以看到当注解 @XmlAccessorType value=PUBLIC_MEMBER 时, JavaBean 和 XML 相互映射,只有有 Getter/Setter 方法或标注 @XmlElement 注解或 public 修饰的属性生效。
- NONE
运行测试类,执行结果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <student> <age>25</age> </student> Student(no=null, name=null, age=25, address=null)
可以看到当注解 @XmlAccessorType value=NONE 时, JavaBean 和 XML 相互映射,只有有 @XmlElement 注解属性生效。
由于内容较多,其他内容详见下一篇文章,如果文章对大家有所帮助,欢迎点赞、关注、评论。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/67522.html