Ver Fonte

添加xml处理类

刘韬 há 3 anos atrás
pai
commit
b7c356b24b

+ 19 - 0
DataFusion/src/com/zskk/tools/Charsets.java

@@ -0,0 +1,19 @@
+package com.zskk.tools;
+
+import java.nio.charset.Charset;
+
+/**
+ * 字符集工具类
+ * Author: L.cm
+ * Date: 2016年3月29日 下午3:44:52
+ */
+public class Charsets {
+
+    // 字符集GBK
+    public static final Charset GBK = Charset.forName("GBK");
+    // 字符集ISO-8859-1
+    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+    // 字符集utf-8
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+}

+ 76 - 0
DataFusion/src/com/zskk/tools/IOUtils.java

@@ -0,0 +1,76 @@
+package com.zskk.tools;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+/**
+ * IOUtils
+ * @author L.cm
+ */
+public abstract class IOUtils {
+    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+    /**
+     * closeQuietly
+     * @param closeable 自动关闭
+     */
+    public static void closeQuietly(Closeable closeable) {
+        try {
+            if (closeable != null) {
+                closeable.close();
+            }
+        } catch (IOException ioe) {
+            // ignore
+        }
+    }
+
+    /**
+     * InputStream to String utf-8
+     *
+     * @param input  the <code>InputStream</code> to read from
+     * @return the requested String
+     * @throws NullPointerException if the input is null
+     * @throws IOException if an I/O error occurs
+     */
+    public static String toString(InputStream input) throws IOException {
+        return toString(input, Charsets.UTF_8);
+    }
+
+    /**
+     * InputStream to String
+     *
+     * @param input  the <code>InputStream</code> to read from
+     * @param charset  the <code>Charset</code>
+     * @return the requested String
+     * @throws NullPointerException if the input is null
+     * @throws IOException if an I/O error occurs
+     */
+    public static String toString(InputStream input, Charset charset) throws IOException {
+        InputStreamReader in = new InputStreamReader(input, charset);
+        StringBuffer out = new StringBuffer();
+        char[] c = new char[DEFAULT_BUFFER_SIZE];
+        for (int n; (n = in.read(c)) != -1;) {
+            out.append(new String(c, 0, n));
+        }
+        IOUtils.closeQuietly(in);
+        IOUtils.closeQuietly(input);
+        return out.toString();
+    }
+
+    /**
+     * InputStream to File
+     * @param input  the <code>InputStream</code> to read from
+     * @param file the File to write
+     * @throws IOException id异常
+     */
+    public static void toFile(InputStream input, File file) throws IOException {
+        OutputStream os = new FileOutputStream(file);
+        int bytesRead = 0;
+        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+        while ((bytesRead = input.read(buffer, 0, DEFAULT_BUFFER_SIZE)) != -1) {
+            os.write(buffer, 0, bytesRead);
+        }
+        IOUtils.closeQuietly(os);
+        IOUtils.closeQuietly(input);
+    }
+}

+ 241 - 0
DataFusion/src/com/zskk/tools/XmlHelper.java

@@ -0,0 +1,241 @@
+package com.zskk.tools;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * xpath解析xml
+ * <pre>
+ *     文档地址:
+ *     http://www.w3school.com.cn/xpath/index.asp
+ * </pre>
+ */
+public class XmlHelper {
+    private final XPath path;
+    private final Document doc;
+
+    private XmlHelper(InputSource inputSource) throws ParserConfigurationException, SAXException, IOException {
+        DocumentBuilderFactory dbf = getDocumentBuilderFactory();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        doc = db.parse(inputSource);
+        path = getXPathFactory().newXPath();
+    }
+
+    private static XmlHelper create(InputSource inputSource) {
+        try {
+            return new XmlHelper(inputSource);
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e);
+        } catch (SAXException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static XmlHelper of(InputStream is) {
+        InputSource inputSource = new InputSource(is);
+        return create(inputSource);
+    }
+
+    public static XmlHelper of(String xmlStr) {
+        StringReader sr = new StringReader(xmlStr.trim());
+        InputSource inputSource = new InputSource(sr);
+        XmlHelper xmlHelper = create(inputSource);
+        IOUtils.closeQuietly(sr);
+        return xmlHelper;
+    }
+
+    private Object evalXPath(String expression, Object item, QName returnType) {
+        item = null == item ? doc : item;
+        try {
+            return path.evaluate(expression, item, returnType);
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 获取String
+     * @param expression 路径
+     * @return String
+     */
+    public String getString(String expression) {
+        return (String) evalXPath(expression, null, XPathConstants.STRING);
+    }
+
+    /**
+     * 获取Boolean
+     * @param expression 路径
+     * @return String
+     */
+    public Boolean getBoolean(String expression) {
+        return (Boolean) evalXPath(expression, null, XPathConstants.BOOLEAN);
+    }
+
+    /**
+     * 获取Number
+     * @param expression 路径
+     * @return {Number}
+     */
+    public Number getNumber(String expression) {
+        return (Number) evalXPath(expression, null, XPathConstants.NUMBER);
+    }
+
+    /**
+     * 获取某个节点
+     * @param expression 路径
+     * @return {Node}
+     */
+    public Node getNode(String expression) {
+        return (Node) evalXPath(expression, null, XPathConstants.NODE);
+    }
+
+    /**
+     * 获取子节点
+     * @param expression 路径
+     * @return NodeList
+     */
+    public NodeList getNodeList(String expression) {
+        return (NodeList) evalXPath(expression, null, XPathConstants.NODESET);
+    }
+
+
+    /**
+     * 获取String
+     * @param node 节点
+     * @param expression 相对于node的路径
+     * @return String
+     */
+    public String getString(Object node, String expression) {
+        return (String) evalXPath(expression, node, XPathConstants.STRING);
+    }
+
+    /**
+     * 获取
+     * @param node 节点
+     * @param expression 相对于node的路径
+     * @return String
+     */
+    public Boolean getBoolean(Object node, String expression) {
+        return (Boolean) evalXPath(expression, node, XPathConstants.BOOLEAN);
+    }
+
+    /**
+     * 获取
+     * @param node 节点
+     * @param expression 相对于node的路径
+     * @return {Number}
+     */
+    public Number getNumber(Object node, String expression) {
+        return (Number) evalXPath(expression, node, XPathConstants.NUMBER);
+    }
+
+    /**
+     * 获取某个节点
+     * @param node 节点
+     * @param expression 路径
+     * @return {Node}
+     */
+    public Node getNode(Object node, String expression) {
+        return (Node) evalXPath(expression, node, XPathConstants.NODE);
+    }
+
+    /**
+     * 获取子节点
+     * @param node 节点
+     * @param expression 相对于node的路径
+     * @return NodeList
+     */
+    public NodeList getNodeList(Object node, String expression) {
+        return (NodeList) evalXPath(expression, node, XPathConstants.NODESET);
+    }
+
+    /**
+     * 针对没有嵌套节点的简单处理
+     * @return map集合
+     */
+    public Map<String, String> toMap() {
+        Element root = doc.getDocumentElement();
+        Map<String, String> params = new HashMap<String, String>();
+
+        // 将节点封装成map形式
+        NodeList list = root.getChildNodes();
+        for (int i = 0; i < list.getLength(); i++) {
+            Node node = list.item(i);
+            if (node instanceof Element) {
+                params.put(node.getNodeName(), node.getTextContent());
+            }
+        }
+        return params;
+    }
+    
+    private static boolean preventedXXE = false;
+
+    private static DocumentBuilderFactory getDocumentBuilderFactory() throws ParserConfigurationException{
+    		DocumentBuilderFactory dbf = XmlHelper.XmlHelperHolder.documentBuilderFactory;
+    		if (!preventedXXE) {
+    			preventXXE(dbf);
+    			preventedXXE = true;
+    		}
+        return dbf;
+    }
+    
+    // https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5
+    private static void preventXXE(DocumentBuilderFactory dbf) throws ParserConfigurationException {
+    		// This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented
+        // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
+        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+
+        // If you can't completely disable DTDs, then at least do the following:
+        // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
+        // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
+
+        // JDK7+ - http://xml.org/sax/features/external-general-entities 
+        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
+
+        // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
+        // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
+
+        // JDK7+ - http://xml.org/sax/features/external-parameter-entities 
+        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+
+        // Disable external DTDs as well
+        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+
+        // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
+        dbf.setXIncludeAware(false);
+        dbf.setExpandEntityReferences(false);
+    }
+
+    private static XPathFactory getXPathFactory() {
+        return  XmlHelper.XmlHelperHolder.xPathFactory;
+    }
+
+    /**
+     * 内部类单例
+     */
+    private static class XmlHelperHolder {
+        private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        private static XPathFactory xPathFactory = XPathFactory.newInstance();
+    }
+
+}