xml文件解析基础和签名

前端之家收集整理的这篇文章主要介绍了xml文件解析基础和签名前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

0. 前言

1.xml文件的解析

1.1 基本的jdk解析xml的原始api解析

  • 声明
    • 1.以下代码块要放到一个类中才能运行
    • dom类型为:org.w3c.dom.*
    • 解析的包:javax.xml.*

1.1.1 输出所xml所有节点内容

/** * 如同js一样的获取节点内容 */
public static void listNl(NodeList nl) {
    int len = nl.getLength();
    for (int i = 0; i < len; i++) {
        Element eltStudent = (Element) nl.item(i);
        Node eltName = eltStudent.getElementsByTagName("name").item(0);
        Node eltAge = eltStudent.getElementsByTagName("age").item(0);
        String name = eltName.getFirstChild().getNodeValue();
        String age = eltAge.getFirstChild().getNodeValue();
        System.out.print("姓名:");
        System.out.println(name);
        System.out.print("年龄:");
        System.out.println(age);
        System.out.println("------------------------");
    }
}
@Test
/** * 输出所xml所有节点内容 */
// 示例地址:http://it.chinawin.net/softwaredev/article-16023.html
public void test_ParseXml1Net_01() throws Exception {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    FileInputStream fis = new FileInputStream(new File(path));
    DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = f.newDocumentBuilder();
    Document doc = builder.parse(fis);
    NodeList nl = doc.getElementsByTagName("student");
    listNl(nl);
}

1.1.2 将字符串转化为xml文件

/** * 将字符串转化为xml文件 *//***/
@Test
public void test_String2Xml() throws Exception {
    // String xmlStr = new String("ASDFADADSD");//报错:[Fatal Error] :1:1: 前言中不允许有内容
    String xmlStr = new String("<?xml version=\"1.0\" encoding=\"GB2312\"?><students><student sn=\"01\"><name>张三</name><age>18</age></student><student sn=\"02\"><name>李四</name><age>20</age></student></students>");
    StringReader sr = new StringReader(xmlStr);
    InputSource is = new InputSource(sr);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(is);
    System.out.println(doc.getClass());//com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl
}

1.1.3 将xml文件转化为字符串

/** * 读取本地文件xml文件为Document对象 */
public static Document test_readXml() throws Exception {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    FileInputStream fis = new FileInputStream(new File(path));
    DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = f.newDocumentBuilder();
    Document doc = builder.parse(fis);
    System.out.println(doc);// ★★[#document: null]注意这里不是打印出来xml文件内容,并不代表没有读到xml文件
    return doc;
}
@Test
/** * 将xml文件转化为字符串 */
public void test_Xml2String() throws Exception {
    Document doc = this.test_readXml();
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer();
    t.setOutputProperty("encoding","UTF-8");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    t.transform(new DOMSource(doc),new StreamResult(bos));
    String xmlStr = bos.toString();
    System.out.println(xmlStr);
}

1.2 使用dom4解析xml

  • 声明
    • 以下代码块要放到一个类中才能运行
    • dom类型和解析的包为:org.dom4j.*
    • ★注意:javax.xml.parsers中的和dom4j中的两种形式的Document不能转换

1.2.1将String转换为Dom4j的Document类对象

/** * 所以在应用时只能用一套xml解析方案,不能交替使用,否则报:ClassCastException异常 * dom4j具体细节操作:参见http://www.cnblogs.com/liuling/archive/2013/02/05/dom4jxml.html *//***/
@Test
public void test_String2Xml_dom4j() throws DocumentException {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    String xmlStr = new String("<?xml version=\"1.0\" encoding=\"GB2312\"?><students><student sn=\"01\"><name>张三</name><age>18</age></student><student sn=\"02\"><name>李四</name><age>20</age></student></students>");
    Document document = DocumentHelper.parseText(xmlStr);// 必须引入dom4j的Document
}

1.2.2 最普通的方法得到xml文件信息

@Test
/** * 方法1:将xml文件看成普通文本文件输出字符信息 */
public void test_OrdTextReadXml() throws Exception {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    File f = new File(path);
    InputStream in = new FileInputStream(f);
    byte[] b = new byte[1024];
    in.read(b);
    in.close();
    System.out.println(new String(b));
}

@Test
/** * ★★方法2:解析后读取xml文件中所有节点信息, */
public void test_Xml2String_dom4j() throws Exception {
    SAXReader sr = new SAXReader();// 获取读取xml的对象。
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    Document doc = sr.read(path);// 得到xml所在位置。然后开始读取。并将数据放入doc中
    Element el_root = doc.getRootElement();// 向外取数据,获取xml的根节点。
    Iterator it = el_root.elementIterator();// 从根节点下依次遍历,获取根节点下所有子节点
    while (it.hasNext()) {// 遍历该子节点
        Object o = it.next();// 再获取该子节点下的子节点
        Element el_row = (Element) o;
        String s = el_row.getText();
        Iterator it_row = el_row.elementIterator();
        while (it_row.hasNext()) {// 遍历节点
            Element el_ename = (Element) it_row.next();// 获取该节点下的所有数据。
            System.out.println(el_ename.getText());
        }
    }
}

@Test
/** * 方法三:使用elements方法进行xml的读取,相当于条件查询,可以根据不同的节点,利用for循环查询该节点下所有的数据。 * 依据不同的xml文件而定 */
public void test_ByElement() throws Exception {
    SAXReader sr = new SAXReader();// 获取读取方式
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    Document doc = sr.read(path);// 读取xml文件,并且将数据全部存放到Document中
    Element root = doc.getRootElement();// 获取根节点
    List list = root.elements("student");// 根据根节点,将根节点下 student中的所有数据放到list容器中。
    for (Object obj : list) {// 这种遍历方式,是jdk1.5以上的版本支持的遍历方式
        Element row = (Element) obj;
        List list_name = row.elements("name");// 获取name节点下所有的内容,存入list_row容器中
        for (Object objempno : list_name) {
            Element el_empno = (Element) objempno;
            System.out.println(el_empno.getName() + ": " + el_empno.getText());// 获取节点下的数据。
        }
    }
}

@Test
/** * 方法四:使用selectNodes()方法 */
public void test_bySelectNode() throws Exception {
    String elementpath = new String("name");// 使用selectNodes获取所要查询xml的节点。
    SAXReader sr = new SAXReader();
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    Document doc = sr.read(path);
    List list = doc.selectNodes(elementpath);
    for (Object obj : list) {// 遍历节点,获取节点内数据。
        Element el = (Element) obj;
        System.out.println(el.getText());
    }
}

2. xml签名

2.1 应用场景

xml作为一种通用跨平台的数据传输的方式,其安全性也受到重视,很多应用或商家在用xml文件之间传输信息时通常要对xml文件进行签名,以确定数据的完整性,以及防篡改。下面是在工作中遇到的签名xml文件的一种方式。

2.2 应用过程

银行身份验证服务接口测试流程

  • 组织数据,生成需要发送到银行的XML文档(未签名)
  • 获取私钥、签名XML文档、发送请求
/** 获取私钥 */
PrivateKey priKey=CertHelper.getPrivateKey();

/** 签名XML文档 */
Document signDoc=CertHelper.signXmlDoc(srcDoc,priKey);
/** 发送请求到网银服务器 */
String result=CertHelper.sendHTTPRequest(signDoc);
  • 获取公钥、验证返回数据
/** * 验证签名数据 */
boolean checkResult=CertHelper.isXmlValid(doc,getPubKey());
  • 处理返回数据:验证用户身份信息的正确性

2.3 签名代码

public class SignXml {
    // 参考文档:http://www.javacodegeeks.com/2013/10/xml-security-with-digital-signature-in-java.html
    /** * @param doc 待签名的xml文档 * @param privateKey 用于对xml签名的私钥 * @return 已签名的xml文档 */
    public static Document signXmlDoc(Document doc,PrivateKey privateKey) throws Exception {
        // 创建XML签名工厂
        XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM");
        DOMSignContext domSignCtx = new DOMSignContext(privateKey,doc.getDocumentElement());
        System.out.println(domSignCtx);
        javax.xml.crypto.dsig.Reference ref = null;
        SignedInfo signedInfo = null;
        try {
            ref = xmlSigFactory.newReference("#CUSTINFOREQ",xmlSigFactory.newDigestMethod(DigestMethod.SHA1,null),Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED,(TransformParameterSpec) null)),null,null);
            signedInfo = xmlSigFactory.newSignedInfo(xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,(C14NMethodParameterSpec) null),xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1,Collections.singletonList(ref));
            System.out.println(signedInfo);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        KeyInfo ki = null;
        // 创建新的XML签名
        XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo,ki);
        try {
            // 对文档签名
            xmlSignature.sign(domSignCtx);
            // ★打印出来xml文档:查看签名信息!【org.dom.Document->String】
            System.out.println("#Begin:get signedXmlDoc********************************");
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            t.setOutputProperty("encoding","GB23121");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            t.transform(new DOMSource(doc),new StreamResult(bos));
            String xmlStr = bos.toString();
            System.out.println(xmlStr);
            System.out.println("#End:get signedXmlDoc********************************");
            return doc;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }
}

应用

原文链接:https://www.f2er.com/xml/296782.html

猜你在找的XML相关文章