XML的优美使用

一、背景

虽然说目前对于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;

具体要看个人的业务情况;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值