众所周知,大家在微信开发工程中,由于微信开发文档中,对于消息的接收发送都是基础xml数据的(太坑了),所以我们需要对XML进行解析转换;

1.我们先引入所需要的依赖 dom4j (解析xml的),xstream(可以将对象,以及复杂对象转换为xml);

<dependency>

<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>

<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>

<!-- 转换xml类 -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.5</version>
</dependency>

 先给大家介绍一下Java 内置的 jaxp xml 解析器获取的方法,以及Document对象(可以忽视不看)

/**
     *  获取 jaxp XML 解析器
     *  位于javax 包中,Java 内置支持
     * @throws ParserConfigurationException 
     */
    
    public static  DocumentBuilder getJaxpXmlBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder;
    }
    
/**
     * jaxp 获取Document 对象,通过一个文件/流对象
     * @throws ParserConfigurationException 
     * @throws IOException 
     * @throws SAXException 
     */
    public static Document getJaxpDocument(DocumentBuilder builder,Object file) throws Exception {
        DocumentBuilder xmlBuilder;
        if((xmlBuilder=builder)==null) {
            xmlBuilder=getJaxpXmlBuilder();
        }
        if(file instanceof File) {
            return xmlBuilder.parse((File)file);
        }else if(file instanceof InputStream) {
            return xmlBuilder.parse((InputStream)file);
        }else {
            return null;
        }
    }

获取dom4j  xml 解析器获取的方法,以及Document对象

    /**
     * dom4j
     * 初始化,获取document 对象通过输入url的方式
     * @param readObject 可以是流,也可以是文件,也可以是URL ,也可以是InputSource
     * @return
     * @throws DocumentException
     */
    public static org.dom4j.Document getDom4jDocument(Object readObject) throws DocumentException {
        SAXReader reader =new SAXReader();
        org.dom4j.Document document ;
        if(readObject instanceof InputStream) {
            document =reader.read((InputStream)readObject);
        }else if(readObject instanceof File) {
            document =reader.read((File)readObject);
        }else if(readObject instanceof URL) {
            document =reader.read((URL)readObject);
        }else if(readObject instanceof InputSource){
            document =reader.read((InputSource)readObject);
        }else {
            //没有匹配的的XML
            document =null;
        }
        
        return document;
    }

 

-------------------------------------------重点方法-------------------

 

2.开始编码 --我会对下面utils类进行解释

先介绍使用XStream 将XML 转换为一个对象,将一个对象转换为XML的方法,并附上实际demo;(需要引入 XStream 包)

(1)XStream 将XML 转换为对象

 

/**
     * 将xml 字符串转换为 pojo 对象
     * 确保已经引入xstream 的jar 包
     * 以及类上面使用了@XStreamAlias("你定义的");
     * @param poClass,转化po的Class
     * @param xml
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T xmlToPojo(Class<T> poClass,String xml) {
        
        XStream xstream =new XStream();
        xstream.processAnnotations(poClass);
        xstream.processAnnotations(getInnerClasses(poClass));
        return (T)xstream.fromXML(xml);
        
        
    }

 

(2). XStream 将一个XML 流转换为对象;

/**
     * 将inputstream转换为 pojo 对象
     * 确保已经引入xstream 的jar 包
     * 以及类上面使用了@XStreamAlias("你定义的");
     * @param poClass
     * @param xml
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T streamToPojo(Class<T> poClass,InputStream stream) {
        
        XStream xstream =new XStream();
        xstream.processAnnotations(poClass);
        xstream.processAnnotations(getInnerClasses(poClass));
        return (T)xstream.fromXML(stream);
        
        
    }

(3).XStream 将对象转换为xml

/**
     * 使用 xstream 将一个人pojo 对象转换为xml 字符串
     * 确保已经引入xstream 的jar 包
     * 以及类上面使用了@XStreamAlias("你定义的");
     * @param pojo
     * @return
     */
    public static <T> String pojoToXml(T pojo) {
        
        Class<?> poClass = pojo.getClass();
        XStream xstream =new XStream();
        xstream.processAnnotations(poClass);
        xstream.processAnnotations(getInnerClasses(poClass));
        return xstream.toXML(pojo);
        
    }
getInnerClasses()方法:
/**
     * 得到一个类的内部类
     * @param clz
     * @return
     */
    public static Class<?>[] getInnerClasses(Class<?> clz) {
        Class<?>[] innerClasses = clz.getClasses();
        if (innerClasses == null) {
          return null;
        }

        List<Class<?>> result = new ArrayList<>();
        result.addAll(Arrays.asList(innerClasses));
        for (Class<?> inner : innerClasses) {
          Class<?>[] innerClz = getInnerClasses(inner);
          if (innerClz == null) {
            continue;
          }

          result.addAll(Arrays.asList(innerClz));
        }

        return result.toArray(new Class<?>[0]);
      }

关于以上方法的demo 如下,让大家加深理解:

package com.baseknow.testclass;

import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;
//pojo
@XStreamAlias("xml")
public class XmlPojo {
    @XStreamAlias("timespace")
    private String times;
    @XStreamAlias("unionid")
    private String unionid;
    @XStreamAlias("openid")
    private String openid;
    @XStreamAlias("items")
    private List<Msg> msg;
    
    public XmlPojo(String times,String unionid,String openid){
        this.times =times;
        this.unionid =unionid;
        this.openid =openid;
    }
    
    @XStreamAlias("item")
    public static class  Msg{
        @XStreamAlias("content")
        private String content;
        @XStreamAlias("tocode")
        private String code;
        public Msg(String content,String code){
            this.content=content;
            this.code=code;
        }
    }
    
    



    public List<Msg> getMsg() {
        return msg;
    }
    public void setMsg(List<Msg> msg) {
        this.msg = msg;
    }
    public String getTimes() {
        return times;
    }
    public void setTimes(String times) {
        this.times = times;
    }
    public String getUnionid() {
        return unionid;
    }
    public void setUnionid(String unionid) {
        this.unionid = unionid;
    }
    public String getOpenid() {
        return openid;
    }
    public void setOpenid(String openid) {
        this.openid = openid;
    }
    
}

main方法:--大家可以进行测试

    public static void main(String[] args) {
        
        XmlPojo po =new XmlPojo("123","123","123");
        
        Msg msg =new Msg("ss","ss");
        Msg msg2 =new Msg("ss1","ss1");
        List li =new ArrayList<>();
        li.add(msg2);li.add(msg);
        po.setMsg(li);
        String pojoToXml = XmlParseUtils.pojoToXml(po);
        System.out.println(pojoToXml);
        //转pojo
        XmlPojo poo = XmlParseUtils.xmlToPojo(po.getClass(), pojoToXml);
        System.out.println(poo);
    }

 

OK,XStream 的常用方法就到这里,对于我来说,用XStream 就够了,很强大,很好扩展,更多需要学习它的api,下面介绍几个也会用到的方法

 

使用common.io 包下的 IOUtils 可以很方便的将input stream 转换为xml 字符串

 public static String xmlStreamToString (HttpServletRequest request) throws Exception{
  String result =IOUtils.toString(request.getInputStream(), "utf-8");
  return result;
}

dom4j 将xml数据流转换为map

    public static Map<String,String> xmlTOMap(HttpServletRequest request) throws Exception{
        
        Map<String,String> map =new HashMap<String,String>();
        SAXReader reader =new SAXReader();
        InputStream ins=null;
        try {
             ins =request.getInputStream();
        } catch (IOException e) {
            
            e.printStackTrace();
        }
        Document docment =reader.read(ins);//读取流对象
        Element root=docment.getRootElement();
        List<Element> list =root.elements();
        for(Element ele:list) {
            
            map.put(ele.getName(), ele.getText());
        }
        
        return map;
        
        
    }

 使用dom4j将XML转换为Map

public static Map<String,String> StrXmlTOMap(String strXml) throws Exception{
        
        Map<String,String> map =new HashMap<String,String>();
        Document docment = DocumentHelper.parseText(strXml);
        Element root=docment.getRootElement();
        List<Element> list =root.elements();
        for(Element ele:list) {
            
            map.put(ele.getName(), ele.getText());
        }
        
        return map;
        
        
    }
    

 

(4)将Map转换为Xml

/*
     * Map转换成Xml
     */
    public static String MapToXml(Map<String,Object> parameters){
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
                sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
            }else {
                sb.append("<"+k+">"+v+"</"+k+">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

 

完整版附上:

package com.baseknow.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.io.IOUtils;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
 * xml 工具类
 * 包含jaxp 解析器的创建;
 * Xpath 解析器的创建;
 * dom4j 解析器
 * dom4j 解析器创建;
 * 获取XML document 对象;
 * 获取Node attriute
 * xml 的转换
 * @author iscys
 *
 */
public class XmlParseUtils {
    
    
    /**
     * 使用 xstream 将一个人pojo 对象转换为xml 字符串
     * 确保已经引入xstream 的jar 包
     * 以及类上面使用了@XStreamAlias("你定义的");
     * @param pojo
     * @return
     */
    public static <T> String pojoToXml(T pojo) {
        
        Class<?> poClass = pojo.getClass();
        XStream xstream =new XStream();
        xstream.processAnnotations(poClass);
        xstream.processAnnotations(getInnerClasses(poClass));
        return xstream.toXML(pojo);
        
    }
    
    /**
     * 将xml 字符串转换为 pojo 对象
     * 确保已经引入xstream 的jar 包
     * 以及类上面使用了@XStreamAlias("你定义的");
     * @param poClass
     * @param xml
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T xmlToPojo(Class<T> poClass,String xml) {
        
        XStream xstream =new XStream();
        xstream.processAnnotations(poClass);
        xstream.processAnnotations(getInnerClasses(poClass));
        return (T)xstream.fromXML(xml);
        
        
    }
    
    /**
     * 将inputstream转换为 pojo 对象
     * 确保已经引入xstream 的jar 包
     * 以及类上面使用了@XStreamAlias("你定义的");
     * @param poClass
     * @param xml
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T streamToPojo(Class<T> poClass,InputStream stream) {
        
        XStream xstream =new XStream();
        xstream.processAnnotations(poClass);
        xstream.processAnnotations(getInnerClasses(poClass));
        return (T)xstream.fromXML(stream);
        
        
    }
    
    /**
     * 使用common 包将流转换为字符串
     * @param stream
     * @return
     * @throws Exception
     */
    public static String xmlStreamToString (InputStream stream) throws Exception{
        String result =IOUtils.toString(stream, "utf-8");
        return result;
        }
    
    
    
    
    
    /**
     *  获取 jaxp XML 解析器
     *  位于javax 包中,Java 内置支持
     * @throws ParserConfigurationException 
     */
    
    public static  DocumentBuilder getJaxpXmlBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder;
    }
    
    /**
     * 获取xpath的实例对象
     */
    public static XPath getXpath() {
          XPathFactory factory = XPathFactory.newInstance();
          XPath xpath = factory.newXPath();
          return xpath;
    }
    
    /**
     * jaxp 获取Document 对象,通过一个文件/流对象
     * @throws ParserConfigurationException 
     * @throws IOException 
     * @throws SAXException 
     */
    public static Document getJaxpDocument(DocumentBuilder builder,Object file) throws Exception {
        DocumentBuilder xmlBuilder;
        if((xmlBuilder=builder)==null) {
            xmlBuilder=getJaxpXmlBuilder();
        }
        if(file instanceof File) {
            return xmlBuilder.parse((File)file);
        }else if(file instanceof InputStream) {
            return xmlBuilder.parse((InputStream)file);
        }else {
            return null;
        }
    }
    
    
    /**
     * dom4j
     * 初始化,获取document 对象通过输入url的方式
     * @param readObject 可以是流,也可以是文件,也可以是URL ,也可以是InputSource
     * @return
     * @throws DocumentException
     */
    public static org.dom4j.Document getDom4jDocument(Object readObject) throws DocumentException {
        SAXReader reader =new SAXReader();
        org.dom4j.Document document ;
        if(readObject instanceof InputStream) {
            document =reader.read((InputStream)readObject);
        }else if(readObject instanceof File) {
            document =reader.read((File)readObject);
        }else if(readObject instanceof URL) {
            document =reader.read((URL)readObject);
        }else if(readObject instanceof InputSource){
            document =reader.read((InputSource)readObject);
        }else {
            //没有匹配的的XML
            document =null;
        }
        
        return document;
    }
    
    /**
     * dom4j
     * 获取根节点
     * @param readObject可以是流,也可以是文件,也可以是URL ,也可以是InputSource
     * @return
     * @throws DocumentException
     */
    public static Element getDom4jRootElement(Object readObject) throws DocumentException {
        org.dom4j.Document document = getDom4jDocument(readObject);
        Element root = document.getRootElement();
        return root;
    }
    
    /**
     * 将node 属性key value 存放到 Properties 中;eg:
     * <test  name ="mytest" class="com.XX.XX">
     * 将name ->mytest
     * class -> com.XXX.XXX
     * 存入Properties
     * 
     */
    public static Properties parseNodeAttributes(Node n) {
          Properties attributes = new Properties();
            NamedNodeMap attributeNodes = n.getAttributes();
            //判断是否为空
            if (attributeNodes != null) {
              for (int i = 0; i < attributeNodes.getLength(); i++) {
                Node attribute = attributeNodes.item(i);
                attributes.put(attribute.getNodeName(), attribute.getNodeValue());
              }
            }
            return attributes;
    }
    
    /**
     * 得到一个类的内部类
     * @param clz
     * @return
     */
    public static Class<?>[] getInnerClasses(Class<?> clz) {
        Class<?>[] innerClasses = clz.getClasses();
        if (innerClasses == null) {
          return null;
        }

        List<Class<?>> result = new ArrayList<>();
        result.addAll(Arrays.asList(innerClasses));
        for (Class<?> inner : innerClasses) {
          Class<?>[] innerClz = getInnerClasses(inner);
          if (innerClz == null) {
            continue;
          }

          result.addAll(Arrays.asList(innerClz));
        }

        return result.toArray(new Class<?>[0]);
      }

}

 

-----为了怕大家对xstream 注解不了解,大致就是这样的

@XStreamAlias("xml")  //在xstream 注解转化时候,会将类名变为xml ,下面也一样
public class Pojo {
    
    @XStreamAlias("namealia")
    private String name;
    @XStreamAlias("agelia")
    private String age;
    @XStreamAlias("lists")
    private List<InnerPojo> list =new ArrayList<>();

 

posted on 2018-08-19 14:15  iscys  阅读(3842)  评论(0编辑  收藏  举报