一、背景
虽然说目前对于xml的使用越来越少,但是在某些业务上还是依稀可见xml使用的影子。比如:银行对接系统中,有的银行系统接口交互的时候还是需要使用xml的方式作为参数和返回值,需要手动解析;那么如何做到优雅的使用xml呢?我们今天就来展示一种优雅的做法。今天不深入底层,我们只做代码的搬运工。
二、使用实例
在一次业务当时我们就使用到了xml方式的数据交互,见接口文档截图:
不论是请求还算是返回都是xml格式,其中的请求参数老长了。
三、代码示例
JAXBUtils.java
package com.action.jaxb.util;
import org.w3c.dom.Node;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringWriter;
/**
* Created by liwei on 2018/4/12.
*/
public class JAXBUtils {
/**
* 获取JAXBContext实例。
* @param c
* @return
*/
@SuppressWarnings("unused")
private static final JAXBContext getJAXBContext(Class<?> c){
JAXBContext jaxbContext=null;
try {
jaxbContext = JAXBContext.newInstance(c);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jaxbContext;
}
/**
* 将报文节点反序列化为实体类
* @param obj
* @param node
* @return
*/
public static final Object documentToModel(Object obj,Node node){
if(node == null){
return null;
}
JAXBContext jaxbContext = getJAXBContext(obj.getClass());
try {
//得到反序列化实例Unmarshaller
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
obj= unmarshaller.unmarshal(node);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
/**
* 将实体类转序列化为对应String类型xml节点
* @param obj
* @return
*/
public static final String modelToStringXML(Object obj){
StringWriter writer= new StringWriter();
JAXBContext jaxbContext = getJAXBContext(obj.getClass());
try {
Marshaller marshaller = jaxbContext.createMarshaller();
//设置序列化的编码格式
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
//设置格式化输出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(obj, writer);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return writer.toString();
}
/**
* 将实体类转序列化为对应node节点
* @param obj 实体类
* @param node 创建的新节点
* @return
*/
public static final Node modelToNode(Object obj,Node node){
JAXBContext jaxbContext = getJAXBContext(obj.getClass());
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(obj, node);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return node;
}
}
XMLS.java
package com.action.jaxb.util;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
/**
* Created by liwei on 2018/4/12.
*/
public class XMLS {
public static Document getDocFromStringXml(File file){
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
Document document = null;
try {
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
document=documentBuilder.parse(file);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return document;
}
}
Student.java
package com.action.jaxb.bo;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Created by liwei on 2018/4/12.
* bo类注解注意点:
*
* @1. 类上的注解 @XmlRootElement 是必不可少的。
* 注解的name属性是可选的,不给节点默认生成为和类名一样,
* 不过全是小写的<student></student>。
* 指定name="studentBean"这生成指定的节点名称,
* 且和指定的大小写一致,有空格的话空格也会出现在标签中。
* <studentBean></studentBean>
* @2. 成员变量/属性上的注解 @XmlElement 可选的注解。
* 不加或者只是加上@XmlElement,没有指定生成节点的名称,
* 默认是和每个属性的名称一致,就是全变成小写。
* 以age为例,<age></age>,如果给上name属性指定生成节点名称,
* 则生成完全和name属性一致的节点出来,和类上的name属性一样。
*/
@XmlRootElement
public class Student {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String address;
// @XmlElement(name="name")
public String getName() {
return name;
}
@XmlElement
public int getAge() {
return age;
}
@XmlElement(name = "studentAddress")
public String getAddress() {
return address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
}
JAXBUtilsTest.java
package com.action.jaxb.test;
import com.action.jaxb.bo.Student;
import com.action.jaxb.util.JAXBUtils;
import com.action.jaxb.util.XMLS;
import org.w3c.dom.Document;
import java.io.File;
/**
* Created by liwei on 2018/4/12.
*/
public class JAXBUtilsTest {
public static void main(String[] args) {
Student student = new Student();
student.setAddress("1");
student.setName("1");
student.setAge(1);
String xml = JAXBUtils.modelToStringXML(student);
System.out.println("-------------------------------");
System.out.println(xml);
File file = new File("D:\\home\\student.xml");
Document dom = XMLS.getDocFromStringXml(file);
Student stu = (Student) JAXBUtils.documentToModel(new Student(), dom);
System.out.println(stu.getAddress()+" "+stu.getAge()+" "+stu.getName()) ;
}
}
主要使用的JAXB解析;以上代码只是一个小demo;
具体要看个人的业务情况;