组件使用总结:使用 JAXB 实现 XML文件和java对象互转

傷城~ 2022-04-22 10:24 219阅读 0赞

JAXB

JAXB:实现xml和java对象互转

  1. JAXB是一个业界的标准,实现XML文件和Java对象的互转。
  2. JAXBJDK 的组成部分。我们不需要下载第三方jar 即可做到轻松转换。

重要类和接口:

  1. JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。
  2. Marshaller接口,将Java对象序列化为XML数据。
  3. Unmarshaller接口,将XML数据反序列化为Java对象。

注解

  1. XMLJava对象的注解:
  2. @XmlType
  3. @XmlElement :将java对象的属性映射为xml的节点
  4. @XmlRootElement:此类对应xml的根元素
  5. @XmlAttribute :把java对象的属性映射为xml的属性
  6. @XmlAccessorType :用于指定由java对象生成xml文件时对java对象属性的访问方式
  7. @XmlJavaTypeAdapter :在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个XmlAdapter
  8. Java对象到XML的注解:
  9. @XmlAccessorOrder :对java对象生成的xml元素进行排序
  10. @XmlTransient :定义某一字段或属性不需要被映射为XML
  11. @XmlElementWrapper :为数组元素或集合元素定义一个父节点

工程实现

demo1:演示xml基本用法,演示@XmlRootElement 、@XmlAccessorType、@XmlElement的用法

基础POJO类
ClassRoomModel包含一个变量name和变量StudentModel列表

  1. public class StudentModel {
  2. private int id; // 学号
  3. private String name; // 名称
  4. private String sex; // 性别
  5. }
  6. @XmlRootElement(name = "classRoom")
  7. @XmlAccessorType(value = XmlAccessType.FIELD)
  8. public class ClassRoomModel {
  9. @XmlElement(name="name")
  10. private String name;
  11. @XmlElement(name="student")
  12. private List<StudentModel> studentModelList;
  13. }

待转化classroom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <classRoom>
  3. <name>配置总名称</name>
  4. <student>
  5. <id>1</id>
  6. <name>张三</name>
  7. <sex></sex>
  8. </student>
  9. <student>
  10. <id>2</id>
  11. <name>李四</name>
  12. <sex></sex>
  13. </student>
  14. </classRoom>

测试类JAXBManager:
创建JAXBContext对象,根据JAXBContext对象创建Unmarshaller 对象,使用Unmarshaller 对象实现将xml转化为ClassRoomModel对象。
根据JAXBContext对象创建Marshaller 对象,使用Marshaller 实现将ClassRoomModel 对象转化为xml文件

  1. JAXBContext jaxbContext = JAXBContext.newInstance(ClassRoomModel.class);
  2. // 从xml文件中读取,并转化为java对象
  3. Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
  4. InputStream classRoomInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/hry/java/xml/classroom.xml");
  5. System.out.println(JAXBManager.class.getClassLoader().getResource(""));
  6. System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
  7. ClassRoomModel classRoomModel = (ClassRoomModel)unmarshaller.unmarshal(classRoomInputStream);
  8. System.out.println(JSON.toJSONString(classRoomModel));
  9. // 保存文件,将Java对象转化为xml文件
  10. Marshaller marshaller = jaxbContext.createMarshaller();
  11. marshaller.marshal(classRoomModel, new File("classroon-save.xml"));

demo2: 演示@XmlAttribute、@XmlJavaTypeAdapter、XmlAdapter用法

基础POJO类:
ClassRoomModel2包含一个变量name和变量StudentModel列表
此demo和上面的类不同,StudentModel2 是使用@XmlAttribute通过xml元素的属性注入值,另外增加属性Date对象

  1. @XmlAccessorType(value = XmlAccessType.FIELD)
  2. public class StudentModel2 {
  3. @XmlAttribute(name = "id")
  4. private int id; // 学号
  5. @XmlAttribute(name = "name")
  6. private String name; // 名称
  7. @XmlAttribute(name = "sex")
  8. private String sex; // 性别
  9. @XmlAttribute(name = "birthDate")
  10. @XmlJavaTypeAdapter(value = DateXmlAdapter.class) // 配置日期转化器
  11. private Date birthDate; // 生日
  12. }
  13. @XmlRootElement(name = "classRoom")
  14. @XmlAccessorType(value = XmlAccessType.FIELD)
  15. public class ClassRoomModel2 {
  16. @XmlElement(name="name")
  17. private String name;
  18. @XmlElement(name="student")
  19. private List<StudentModel2> studentModelList;
  20. }

待转化xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <classRoom>
  3. <name>配置总名称</name>
  4. <student id="1" name="张三" sex="男" birthDate="1999-10-22" />
  5. <student id="2" name="李四" sex="女" birthDate="1997-12-23" />
  6. </classRoom>

XmlAdapter用法:
StudentModel2 里的成员变量birthDate的新注解@XmlJavaTypeAdapter(value = DateXmlAdapter.class),实现日期String和Date的相互转化

  1. public class DateXmlAdapter extends XmlAdapter<String, Date> {
  2. // 时间
  3. private static final ThreadLocal<SimpleDateFormat> simpleDateFormatThreadLocalYYYYMMDD = new ThreadLocal<SimpleDateFormat>(){
  4. @Override
  5. protected SimpleDateFormat initialValue() {
  6. return new SimpleDateFormat("yyyy-MM-dd");
  7. }
  8. };
  9. @Override
  10. public Date unmarshal(String v) throws Exception {
  11. System.out.println(v);
  12. return simpleDateFormatThreadLocalYYYYMMDD.get().parse(v);
  13. }
  14. @Override
  15. public String marshal(Date v) throws Exception {
  16. System.out.println(v);
  17. return simpleDateFormatThreadLocalYYYYMMDD.get().format(v);
  18. }
  19. }

测试类JAXBManager:
用法和第一个demo相同,详细见代码

  1. public static void main(String[] args){
  2. try {
  3. JAXBContext jaxbContext = JAXBContext.newInstance(ClassRoomModel2.class);
  4. // 从xml文件中读取,并转化为java对象
  5. Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
  6. InputStream classRoomInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/hry/java/xml/classroom2.xml");
  7. System.out.println(JAXBManager2.class.getClassLoader().getResource(""));
  8. System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
  9. ClassRoomModel2 classRoomModel = (ClassRoomModel2)unmarshaller.unmarshal(classRoomInputStream);
  10. System.out.println(JSON.toJSONString(classRoomModel));
  11. // 保存文件,将Java对象转化为xml文件
  12. Marshaller marshaller = jaxbContext.createMarshaller();
  13. marshaller.marshal(classRoomModel, new File("classroon-save2.xml"));
  14. } catch (JAXBException e) {
  15. e.printStackTrace();
  16. }
  17. }

异常处理

如果不在类加上@XmlAccessorType(value = XmlAccessType.FIELD),则可能抛出如下异常。@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误,异常如下:

  1. com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
  2. 类的两个属性具有相同名称 "name"
  3. this problem is related to the following location:
  4. at public java.lang.String com.hry.java.xml.model.ClassRoomModel.getName()
  5. at com.hry.java.xml.model.ClassRoomModel
  6. this problem is related to the following location:
  7. at private java.lang.String com.hry.java.xml.model.ClassRoomModel.name
  8. at com.hry.java.xml.model.ClassRoomModel

代码

以上的详细代码见这里Github

发表评论

表情:
评论列表 (有 0 条评论,219人围观)

还没有评论,来说两句吧...

相关阅读