1. JAXB - Java Architecturefor XML Binding - 面向XML绑定的Java体系结构
1.1 注解
// 1. 需要解析什么访问权限的javaBean字段 == 如果是私有字段,类上必须加上此注解
@XmlAccessorType(XmlAccessType.FIELD)
// 2. 使用什么标签名包裹该类的全部属性
@XmlRootElement(name="student")
// 3. 该类的属性字段的值需要什么标签进行包裹
@XmlElement(name="name",required = true)
// 4. 属性字段是容器对象如Collection,需要什么标签包裹该字段遍历的元素
@XmlElementWrapper(name = "students")
@XmlElement(name="name") // 遍历的每个JavaBean的属性值由该 定义的标签进行包裹
// 5. 可以迭代容器字段
@XmlAnyElement
// 4. 定义属性字段序列化、反序列化的顺序
@XmlType(propOrder = {"id", "name"})
//在XmlRootElement根这个节点添加属性
@XmlAttribute(name = "xx", required = true)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
1.2 使用
Student.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD) //定义xml序列化的字段类型
@XmlRootElement(name="student") //定义xml中跟属性
public class Student {
//xml属性映射
@XmlElement(name="name",required = true)
private String name;
@XmlElement(name="year",required = true)
private Integer year;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
student.xml
<?xml version="1.0"?>
<student>
<name>lrc</name>
<year>22</year>
</student>
- 1
- 2
- 3
- 4
- 5
测试1 - 反序列化xml文件成JavaBean对象
@Test
public void test1() throws Exception {
Class clazz = Student.class;
//实参中包含需要解析的类
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
//xml文件解析成JavaBean对象器
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
//序列化
File file = new File("C:\\Users\\Administrator\\Desktop\\student.xml");
Object student = unmarshaller.unmarshal(file);
System.out.println(student);
System.out.println(student.getClass().getName());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
测试2 - 序列化普通JavaBean对象
@Test
public void test2() throws JAXBException {
Class clazz = Student.class;
//实参中包含需要解析的类
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
//javaBean序列化xml文件器
Marshaller marshaller = jaxbContext.createMarshaller();
//是否格式化xml文件
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
//序列化
Student student = new Student("lcj", 25);
marshaller.marshal(student, new File("C:\\Users\\Administrator\\Desktop\\student2.xml"));
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
测试3 - 序列化JavaBean对象字段中含有容器Collection -> xml字符串
Student.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="studentxx")
public class Student extends BaseDomain implements Play{
@XmlElement(name="name",required = true)
private String name;
@XmlElement(name="year",required = true)
private Integer year;
@Override
public void play() {
System.out.println(name + ":正在玩游戏");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
Teacher.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement(name = "teacher")
@XmlAccessorType(XmlAccessType.FIELD)
public class Teacher {
@XmlElement(name = "teacherName")
String name;
@XmlElement(name = "teacherSubject")
String subject;
@XmlElementWrapper(name = "students") //将该字段的内容写在节点里面
@XmlElement(name = "student") //指定每个Student对象的父标签,并且Student的@XmlRootElement属性失效
List<Student> students;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
测试JavaBean中含有容器字段
@Test
public void test6() throws JAXBException {
//1. 序列化的对象
List<Student> students = new ArrayList<>();
students.add(new Student("lrc", 20));
students.add(new Student("lcj", 25));
Teacher teacher = new Teacher("昌老师", "数学", students);
JAXBContext jaxbContext = JAXBContext.newInstance(Teacher.class);
// 2. xml序列化器
Marshaller marshaller = jaxbContext.createMarshaller();
//序列化后的xml是否需要格式化输出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//取消这个标签的显示
marshaller.setProperty(Marshaller.JAXB_FRAGMENT,true);
//编码格式
marshaller.setProperty(Marshaller.JAXB_ENCODING,"utf-8");
// 3. 序列化
StringWriter sw = new StringWriter();
marshaller.marshal(teacher, sw);
//4.打印
System.out.println(sw.toString());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
测试4 - 序列化容器对象
@Test
public void test7() throws JAXBException {
//必须使用包装类 - 否则输出不了任何东西
List<Student> students = new ArrayList<>();
students.add(new Student("lrc", 20));
students.add(new Student("lcj", 25));
QName tagName = new QName("myStudents");
JAXBElement<ListWrapper> jaxbElement = new JAXBElement<>(tagName, ListWrapper.class, new ListWrapper(students));
//生成xml上下文 - 定义解析的类型
JAXBContext jaxbContext = JAXBContext.newInstance(Student.class, ListWrapper.class);
// 2. xml序列化器
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 3. 序列化
StringWriter sw = new StringWriter();
marshaller.marshal(jaxbElement, sw);
//4.打印
System.out.println(sw.toString());
}
//内部类必须是静态 - list包装类
@AllArgsConstructor
static class ListWrapper {
@XmlAnyElement //必须使用这个注解 - 可以迭代容器元素 - 可以生效Student的@XmlRootElement(name="studentxx")注解
//@XmlElement(name = "student") - 上面的注解可以替换成这个 - 取代了Student的@XmlRootElement(name="studentxx")注解
List<Student> students;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
测试5 - 复杂报文解析
参考文章:https://blog.csdn.net/wn084/article/details/80853587
//@XmlAccessorType(XmlAccessType.FIELD)
如果你得字段是private类型且将@XmlElement放在属性上面,则必须在类上添加这个注解
- 1
- 2
RowCrmResult.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Accessors(chain = true)
@XmlAccessorType(XmlAccessType.FIELD) //定义xml序列化的字段类型
@XmlRootElement(name = "outputdatas")
public class RowCrmResult {
/**
* 结果里面的状态码
*/
@XmlElement(name = "resultcode", nillable = true)
public String resultcode;
/**
* 结果里面的失败原因
*/
@XmlElement(name = "reason", nillable = true)
public String reason;
@XmlElementWrapper(name = "results")
@XmlElement(name = "result", nillable = true)
public List<Result> results;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Accessors(chain = true)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "result")
public static class Result {
@XmlAttribute(name = "set_id")
private String setId;
@XmlAttribute(name = "rows")
private Integer rowNum;
@XmlAttribute(name = "cols")
private Integer colNum;
@XmlElement(name = "row", nillable = true)
private List<Row> rows;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Accessors(chain = true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static class Row {
@XmlAttribute(name = "rownum")
private Integer rownum;
@XmlElement(name = "col", nillable = true)
private List<Col> cols;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Accessors(chain = true)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public static class Col {
@XmlAttribute(name = "colnum")
private String colnum;
@XmlAttribute(name = "param_id")
private String paramId;
@XmlAttribute(name = "param_name")
private String paramName;
@XmlValue
private String content;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
开始解析
Test.java
/**
* 格式化响应内容 == 去除其他没用的字符,并格式化XML
* 使用的是hutool工具包
* @param content
* @return
*/
public static String formatResponseContent(String content) {
content = StrUtil.replace(content, ", "");
content = StrUtil.replace(content, "]]>", "");
content = StrUtil.subBetween(
原文:https://blog.csdn.net/weixin_39651356/article/details/122045677