xml报文需求实战

本文介绍了一种XML报文解析的实战案例,包括如何使用Java读取和解析XML文件,提取关键信息,并进行数据处理。文章详细展示了从接收XML文件到解析并存储数据的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


为了大家快速理解报文解析是做什么的?
简单的给大家按照企业的解析思路,给大家做了一个需求实战的真实流程,解析的报文每个厂商都不一样,因此,我自己造了一个xml报文,但是解析过程都是一样的!

1. 工具类

package com.gblfy.test.util;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class XmlFileDealUtils {
    /**
     * 获取本地目录下的文件名
     *
     * @param localPath 本地文件目录
     * @param fileName  本地文件名
     * @throws Exception
     */
    public static void getLocalFileNme(String localPath, String fileName) throws Exception {
        List<String> fileNames = getCurrentDirAllFileList(localPath, fileName);
        System.out.println(fileNames.size());
        if (fileNames != null) {
            for (String ff : fileNames) {
                System.out.println("File name under directory : " + ff);
                // 5.解析指定目录下的指定xml报文文件
                analysisInputMsg(localPath, fileName);
            }
        }
    }

    /**
     * 解析本地xml文件
     *
     * @param localPath
     * @param fileName
     * @throws Exception
     */
    public static void analysisInputMsg(String localPath, String fileName) throws Exception {
        // 创建一个DocumentBuilderFactory的对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 创建一个DocumentBuilder的对象
        try {
            // 创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            // 通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
//		    Document document = db.parse("books.xml");
            Document document = db.parse("D:" + File.separator + "dd" + File.separator + "books20190222.xml");
            // 获取所有book节点的集合
            NodeList bookList = document.getElementsByTagName("book");
            // 通过nodelist的getLength()方法可以获取bookList的长度
            System.out.println("一共有" + bookList.getLength() + "本书");
            // 遍历每一个book节点
            for (int i = 0; i < bookList.getLength(); i++) {
                System.out.println("=================下面开始遍历第" + (i + 1) + "本书的内容=================");
                // 通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始
                Node book = bookList.item(i);
                // 获取book节点的所有属性集合
                NamedNodeMap attrs = book.getAttributes();
                System.out.println("第 " + (i + 1) + "本书共有" + attrs.getLength() + "个属性");
                // 遍历book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    // 通过item(index)方法获取book节点的某一个属性
                    Node attr = attrs.item(j);
                    // 获取属性名
                    System.out.print("属性名:" + attr.getNodeName());
                    // 获取属性值
                    System.out.println("--属性值" + attr.getNodeValue());
                }
                // 解析book节点的子节点
                NodeList childNodes = book.getChildNodes();
                // 遍历childNodes获取每个节点的节点名和节点值
                System.out.println("第" + (i + 1) + "本书共有" + childNodes.getLength() + "个子节点");
                for (int k = 0; k < childNodes.getLength(); k++) {
                    // 区分出text类型的node以及element类型的node
                    if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
                        // 获取了element类型节点的节点名
                        System.out.print("第" + (k + 1) + "个节点的节点名:" + childNodes.item(k).getNodeName());
                        // 获取了element类型节点的节点值
                        System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue());
                        // System.out.println("--节点值是:" + childNodes.item(k).getTextContent());
                    }
                }
                System.out.println("======================结束遍历第" + (i + 1) + "本书的内容=================");
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 写请求报文至本地目录文件
     *
     * @param localFilePath 文件的绝对路径
     * @param content       文件内容
     * @param encoding      文件内容编码
     * @throws IOException
     */
    public static void write(String localFilePath, String fileNme, String content, String encoding) throws IOException {
        boolean flag = createDir(localFilePath);
        System.out.println("****" + flag);
        File file = new File(localFilePath + fileNme);
        file.delete();
        file.createNewFile();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
        writer.write(content);
        writer.close();
    }

    /**
     * 本地创建文件夹
     *
     * @param destDirName
     * @return
     * @author gblfy
     */
    public static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (!dir.exists()) {// 本地目录不存在创建
            dir.mkdirs();
            return true;
        }
        System.out.println("#本地目录已存在!:" + destDirName);
        return false;
    }

    /**
     * 遍历本地目录当前日期下面文件列表
     *
     * @param localFilePath
     * @return
     * @throws Exception
     */
    public static List<String> getCurrentDirAllFileList(String localFilePath, String fileName) throws Exception {
        List<String> list = new ArrayList<String>();
        // 获得指定目录下所有文件名
        File file = new File(localFilePath);
        File[] listFiles = null;
        listFiles = file.listFiles();
        if (listFiles != null && listFiles.length > 0) {
            for (File ff : listFiles) {
                if (ff.isFile() && ff.getName().equals(fileName)) {
                    list.add(ff.getName());
                }
            }
        }
        return list;
    }

    /**
     * 本地保存报文
     *
     * @param fileName
     * @param fileContext
     * @param writeTempFielPath
     * @return
     * @author guobin
     */
    public static boolean saveLocal(String fileName, String fileContext, String writeTempFielPath) throws IOException {
        BufferedWriter bw = null;
        try {
            File f = new File(writeTempFielPath + File.separator + fileName);
            bw = new BufferedWriter(new FileWriter(f, true));
            bw.write(fileContext.replaceAll("\n", "\r\n"));
            bw.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("#本地保存报文失败" + "[" + fileName + "]");
        } finally {
            bw.close();
        }
        return false;
    }

    /**
     * 根据当前日期生成文件备份子目录 传入格式:2018-11-16 返回格式:20181116
     *
     * @param inputDate 日期
     * @return 字符串
     */
    public static String getSubDir(String inputDate) {

        StringBuffer bufSubDir = new StringBuffer();
        bufSubDir.append(inputDate.substring(0, 4));
        bufSubDir.append(inputDate.substring(5, 7));
        bufSubDir.append(inputDate.substring(8, 10));
        return bufSubDir.toString();
    }

}

2. 测试类

package com.sinosoft.fis.test.demo;

import com.sinosoft.fis.test.util.XmlFileDealUtils;

import java.io.File;

/**
 * xml报文需求实战
 * <p>
 * 1.服务方接收 xml 文件。
 * 2.接收报文后,将文件写到指定目录。
 * 3.对本地的xml报文文件解析,取出每一个节点信息,进行数据落库操作。
 */
public class WriteFileAnalysisInputMsg {


    /**
     * 根据需求,将请求报文,保存到本地
     * 1. 文件名日期格式处理
     * 2.拼接本地保存的文件名
     * 3.将接收的报文写到本地指定目录
     * 4.获取指定目录下的文件名
     * 5.解析指定目录下的指定xml报文文件
     */
    public static void main(String[] args) throws Exception {

        //第三方发送的xml报文
        String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<bookstore>\r\n"
                + "    <book id=\"1\">\r\n" + "        <name>钢铁是怎样炼成的</name>\r\n" + "        <author>奥斯特洛夫斯基</author>\r\n"
                + "        <year>2014</year>\r\n" + "        <price>89</price>\r\n" + "    </book>\r\n"
                + "    <book id=\"2\">\r\n" + "        <name>安徒生童话</name>\r\n" + "        <year>2004</year>\r\n"
                + "        <price>77</price>\r\n" + "        <language>English</language>\r\n" + "    </book>    \r\n"
                + "</bookstore>";


        //1. 文件名日期格式处理
        String inputDate = "2019-02-22";
        inputDate = XmlFileDealUtils.getSubDir(inputDate);
        //2.拼接本地保存的文件名
        String fileName = "books" + inputDate + ".xml";
        String localFilePath = "D:" + File.separator + "dd" + File.separator;
        // 3.将接收的报文写到本地指定目录
        XmlFileDealUtils.write(localFilePath, fileName, content, "utf-8");
        // 4.获取指定目录下的文件名
        XmlFileDealUtils.getLocalFileNme(localFilePath, fileName);
    }
}

3. 工具发送报文

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book id="1">
        <name>钢铁是怎样炼成的</name>
        <author>奥斯特洛夫斯基</author>
        <year>2014</year>
        <price>89</price>
    </book>
    <book id="2">
        <name>安徒生童话</name>
        <year>2004</year>
        <price>77</price>
        <language>English</language>
    </book>    
</bookstore>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gblfy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值