Xml解析与生成
1 背景
声明:本文不涉及XML节点操作,仅仅适用于Bean与XML的转化过程。
当第三方接口传输格式为XML格式,拼接XML格式参数以及解析XML响应结果是无法逃避的问题。类似这种场景,不需要操作XML的DOM节点,只要会XML与DOM转化即可。
2 XML解析与生成
2.1 工具类
由于不需要操作XML节点,所以不需要引入类似dom4j之类的解析框架,仅仅使用JDK 1.8 的API即可。为了更好的操作,需要编写合适的工具类。下面给出代码,需要的请拿走。
package xyz.yq56.sdk.util;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
/**
* @author yiqiang
*/
@SuppressWarnings("unused")
public class JaXmlBeanUtil {
public static String convertToXml(Object obj) {
return convertToXml(obj, "UTF-8");
}
/**
* JavaBean转换成xml
*/
public static String convertToXml(Object obj, String encoding) {
String result = null;
try {
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* xml转换成JavaBean
*/
@SuppressWarnings("unchecked")
public static <T> T convertToJavaBean(String xml, Class<T> c) {
T t = null;
try {
JAXBContext context = JAXBContext.newInstance(c);
Unmarshaller unmarshaller = context.createUnmarshaller();
t = (T) unmarshaller.unmarshal(new StringReader(xml));
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
}
2.2 相关注解
XML与Bean的转化依赖于注解,下面给出常用注解
- @XmlRootElement(name = “response”)
该注解表明这是XML的根节点,必须存在。XML的解析与生成会从标有此注解的地方开始,而中间对象标注或不标注不影响结果。 - @XmlAccessorType(XmlAccessType.FIELD)
常与@XmlRootElement联用,表明所有属性均会被解析。如果设置为XmlAccessType.PROPERTY,则只会解析拥有get和set方法的属性。 - @XmlElementWrapper
当使用了集合时,需要标注此注解。会在外层包裹一个集合标签,默认使用属性名称。但这样会出现一个问题,集合标签和元素标签都使用的同一个属性名称。为解决这个问题,一般还需要添加@XmlElement改变元素的名称。 - @XmlElement
这个注解可以改变属性对应的XML节点名称,类似@JsonProperty - @XmlJavaTypeAdaptor
标注在接口 属性上,为接口指定具体的实现类。当属性为接口时,必须指定该注解。
2.3 使用步骤
2.3.1 定义XML对应的Bean
定义三个Bean,具体注解含义见2.2
@Getter
@Setter
@XmlRootElement(name = "response")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ResponseElement {
private int id;
private String name;
@XmlElementWrapper
@XmlElement(name = "user")
private List<User> userList;
}
@Getter
@Setter
public class User {
private int id;
private String username;
private String password;
}
//测试继承
@Getter
@Setter
@XmlRootElement
public class ResponseExt extends ResponseElement{
private String field1;
}
2.3.2 使用工具类进行解析
- 生成XML:
String xml=JaXmlBeanUtil.convertToXml(requestElement)
- 解析XML:
ResponseExt responseExt=JaXmlBeanUtil.convertToJavaBean(xml, ResponseExt.class);
3 效果展示
3.1 测试代码
/**
* @author Yi Qiang
* @version 1.0.0
* @date 2020/10/12 19:05
*/
@Slf4j
public class XmlTest {
private static ObjectMapper mapper=new ObjectMapper();
public void marshal() {
ResponseElement response=new ResponseElement();
response.setId(1);
response.setName("yq");
User user=new User();
user.setId(1);
user.setUsername("test");
user.setPassword("123456");
User user2=new User();
user2.setId(2);
user2.setUsername("test2");
user2.setPassword("1234562");
List<User> list=new ArrayList<User>();
list.add(user2);
list.add(user);
response.setUserList(list);
log.info(JaXmlBeanUtil.convertToXml(response));
ResponseExt ext=new ResponseExt();
ext.setField1("field1");
ext.setUserList(list);
ext.setId(3);
ext.setName("test3");
log.info(JaXmlBeanUtil.convertToXml(ext));
}
public void unmarshal() throws JsonProcessingException {
String xml="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<responseExt>\n" +
" <id>3</id>\n" +
" <name>test3</name>\n" +
" <userList>\n" +
" <user>\n" +
" <id>2</id>\n" +
" <password>1234562</password>\n" +
" <username>test2</username>\n" +
" </user>\n" +
" <user>\n" +
" <id>1</id>\n" +
" <password>123456</password>\n" +
" <username>test</username>\n" +
" </user>\n" +
" </userList>\n" +
" <field1>field1</field1>\n" +
"</responseExt>";
ResponseElement responseElement = JaXmlBeanUtil.convertToJavaBean(xml, ResponseExt.class);
log.info(mapper.writeValueAsString(responseElement));
}
public static void main(String[] args) throws JsonProcessingException {
XmlTest test=new XmlTest();
test.marshal();
log.info("");
test.unmarshal();
}
}
3.2 运行结果
14:08:04.936 [main] INFO xyz.yq56.test.XmlTest - <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<id>1</id>
<name>yq</name>
<userList>
<user>
<id>2</id>
<password>1234562</password>
<username>test2</username>
</user>
<user>
<id>1</id>
<password>123456</password>
<username>test</username>
</user>
</userList>
</response>
14:08:05.018 [main] INFO xyz.yq56.test.XmlTest - <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<responseExt>
<id>3</id>
<name>test3</name>
<userList>
<user>
<id>2</id>
<password>1234562</password>
<username>test2</username>
</user>
<user>
<id>1</id>
<password>123456</password>
<username>test</username>
</user>
</userList>
<field1>field1</field1>
</responseExt>
14:08:05.018 [main] INFO xyz.yq56.test.XmlTest -
14:08:05.274 [main] INFO xyz.yq56.test.XmlTest - {"id":3,"name":"test3","userList":[{"id":2,"username":"test2","password":"1234562"},{"id":1,"username":"test","password":"123456"}],"field1":"field1"}
4 结语
对于第三方接口对接,难免遇到XML传输。如果本文对你有所帮助,请给我点个赞!!与君共勉