背景:
虽然说现在主流参数格式是json,但是还有一些老系统使用的是xml报文,比如银行等系统。本文主要讲了,使用Jackson进行对象与xml之间的转换。
注:源码地址见文章结尾处
Maven依赖
<dependencies>
<!-- junit 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
</dependency>
<!-- jackson相关 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.11</version>
</dependency>
</dependencies>
创建Xml工具类
package com.example.util;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.IOException;
/**
* bean 转 xml
* xml 转 bean 转换工具类
* * @author 码农猿
*/
public class XmlUtils {
private static final ObjectMapper OBJECT_MAPPER = new XmlMapper();
/**
* 将Object 转 XML 字符串
*
* @param object 要转换的对象
* @throws JsonProcessingException
*/
public static String objectToXmlString(Object object) throws JsonProcessingException {
//美化输出的 xml 字符串
OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
//字段为null,自动忽略,不再序列化
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return OBJECT_MAPPER.writeValueAsString(object);
}
/**
* XMl >
* 将XML字符串转换为JavaBean对象,
* ObjectMapper还提供了很多重载方法,详情查看源码,这里不一一列举
*
* @param xmlStr xml字符串
* @param tClass 转换成的类
* @param <T> 转换成的类
* @throws IOException
*/
public static <T> T xmlStringToObject(String xmlStr, Class<T> tClass) throws IOException {
//字段为null,自动忽略,不再序列化
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return OBJECT_MAPPER.readValue(xmlStr, tClass);
}
}
普通简单类转换
Bean测试对象
package com.example.demo1;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.math.BigDecimal;
/**
* 人员测试
*
* @author 码农猿
*/
@JacksonXmlRootElement(localName = "user")
public class UserDemo {
/**
* 用户名
*/
@JacksonXmlProperty(localName = "user_name")
private String username;
/**
* 密码
*/
@JacksonXmlProperty(localName = "password")
private String userPassword;
/**
* 手机号
*/
private String phone;
/**
* 年龄
*/
private Integer age;
/**
* 体重
* 注:小数属性测试
*/
@JacksonXmlProperty(localName = "body_weight")
private BigDecimal bodyWeight;
/**
* 是否管理员
* 注:布尔属性测试
*/
@JacksonXmlProperty(localName = "is_admin")
private Boolean isAdmin;
public UserDemo() {
}
public UserDemo(String username, String userPassword, String phone, Integer age, BigDecimal bodyWeight, Boolean isAdmin) {
this.username = username;
this.userPassword = userPassword;
this.phone = phone;
this.age = age;
this.bodyWeight = bodyWeight;
this.isAdmin = isAdmin;
}
//省略 get/set/toString 方法
}
测试
/**
* xml 转 bean 测试
*/
@Test
public void xmlToBeanTest1() throws Exception {
//生成 xml
String xmlStr = this.getXmlString();
System.out.print("bean 转 xml字符串 :" + xmlStr);
//转换为对象
UserDemo user = XmlUtils.xmlStringToObject(xmlStr, UserDemo.class);
System.out.println("xml 转 bean :" + user);
}
private String getXmlString() throws Exception {
UserDemo user1 = new UserDemo("张三", "123456", "13233333366", 12, new BigDecimal("120.33"), true);
return XmlUtils.objectToXmlString(user1);
}
结果图示
带有嵌套类转换
Bean测试对象
package com.example.demo2;
import com.fasterxml.jackson.dataformat.xml.annotation.*;
import java.util.List;
/**
* 学生测试 类
*
* @author 码农猿
*/
@JacksonXmlRootElement(localName = "student")
public class Student {
/**
* 姓名
*/
@JacksonXmlProperty(localName = "student_name")
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 班级
*/
@JacksonXmlProperty(localName = "class")
private StudentClass studentClass;
/**
* 手机号 (多个)
*/
@JacksonXmlElementWrapper(localName = "phone_list")
@JacksonXmlProperty(localName = "phone")
private List<StudentPhone> phoneList;
//省略 get、set、toString
}
package com.example.demo2;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
/**
* 学生- 班级属性 类
*
* @author 码农猿
*/
public class StudentClass {
/**
* 班级编号
*/
@JacksonXmlProperty(localName = "class_number")
private Integer classNumber;
/**
* 班主任 手机号
*/
@JacksonXmlProperty(localName = "teacher_phone")
private String teacherPhone;
/**
* 班主任 姓名
*/
@JacksonXmlProperty(localName = "teacher_name")
private String teacherName;
public StudentClass() {
}
public StudentClass(Integer classNumber, String teacherName, String teacherPhone) {
this.classNumber = classNumber;
this.teacherName = teacherName;
this.teacherPhone = teacherPhone;
}
//省略 get、set、toString
}
package com.example.demo2;
/**
* 学生- 手机属性 类
*
* @author 码农猿
*/
public class StudentPhone {
/**
* 号码
*/
private String number;
/**
* 归属地
*/
private String address;
public StudentPhone() {
}
public StudentPhone(String number, String address) {
this.number = number;
this.address = address;
}
//省略 get、set、toString
}
测试
/**
* xml 转 bean 测试
*/
@Test
public void xmlToBeanTest1() throws Exception {
//生成 xml
String xmlStr = this.getStudentXml();
System.out.print("bean 转 xml字符串 :" + xmlStr);
//转换为对象
Student student = XmlUtils.xmlStringToObject(xmlStr, Student.class);
System.out.println("xml 转 bean :" + student);
}
private String getStudentXml() throws Exception {
StudentClass studentClass = new StudentClass(1, "张老师", "13235627899");
List<StudentPhone> phoneList = new ArrayList<>(2);
StudentPhone phone1 = new StudentPhone("13235777777", "上海");
StudentPhone phone2 = new StudentPhone("13235777778", "杭州");
phoneList.add(phone1);
phoneList.add(phone2);
Student student = new Student();
student.setName("学生李四");
student.setAge(16);
student.setStudentClass(studentClass);
student.setPhoneList(phoneList);
return XmlUtils.objectToXmlString(student);
}
结果图示
公共请求格式转换
package com.example.demo3;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
/**
* 公共请求 类
*
* @author 码农猿
*/
@JacksonXmlRootElement(localName = "request")
public class RequestDemo<T> {
/**
* 请求方 appid
*/
@JacksonXmlProperty(localName = "app_id")
private String appId;
/**
* 版本
*/
@JacksonXmlProperty(localName = "version")
private String version;
/**
* 签名
*/
@JacksonXmlProperty(localName = "sign")
private String sign;
/**
* 请求内容
*/
private T content;
public RequestDemo() {
}
public RequestDemo(String appId, String version, String sign) {
this.appId = appId;
this.version = version;
this.sign = sign;
}
//省略 get、set、toString
}
测试
/**
* xml 转 bean 测试
*/
@Test
public void xmlToBeanTest1() throws Exception {
//获取 xml
String xmlStr = this.getRequestXml();
System.out.print("bean 转 xml字符串 :" + xmlStr);
RequestDemo<UserDemo> requestDemo = XmlUtils.xmlStringToObject(xmlStr, RequestDemo.class);
System.out.println("xml 转 bean :" + requestDemo);
}
private String getRequestXml() throws Exception {
UserDemo user = new UserDemo("李四", "123456", "133331112266", 12, new BigDecimal("120.33"), true);
RequestDemo<UserDemo> requestDemo = new RequestDemo<UserDemo>("10001", "1.0", "sign...123456");
requestDemo.setContent(user);
//转换 xml
return XmlUtils.objectToXmlString(requestDemo);
}
结果图示
源码地址: 传送门
附录
注解介绍
- @JacksonXmlRootElement
含义: 用于类名,表示xml根节点名称,若不设置,默认是此类的名称
属性1: namespace > 指定XML命名空间的名称
属性2: localName > 指定节点名称,默认类名
命名空间示例:<user xmlns="http://1234">
- @JacksonXmlProperty
含义:指定包装标签名,或者指定标签内部属性名
属性1: namespace > 指定XML命名空间的名称
属性2: localName > 指定节点名称
属性3: isAttribute >more 指定该属性作为XML的属性,还是作为子标签,默认false
示例: <request version="1.0" > 其中version就是属性的意思
-
@JacksonXmlElementWrapper
含义:可用于指定List等集合类,外围标签名
属性1: namespace > 指定XML命名空间的名称
属性2: localName > 指定节点名称
属性3: useWrapping > 是否作为外围标签,默认true -
@JacksonXmlText
含义:注解将属性直接作为未被标签包裹的普通文本表现。
属性1: value > 默认true -
@JacksonXmlCData
含义:将属性包裹在CDATA标签中。
属性1: value > 默认true
示例: <phone><![CDATA[13233333366]]></phone>