IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 工行银企直联(dom4j+java无中间件版) -> 正文阅读

[网络协议]工行银企直联(dom4j+java无中间件版)

工行银企直联(dom4j无中间件版)

最近,接手了工行银企直联的任务,在网上找了很多,发现能一次说清的文章很少,此篇文章专为第一次接触银企直联的同学准备。

1、准备包:dom4j(自行百度,如果这一步都不知道怎么做,接下来的过程也就别看了)

2、逻辑

3、Http的Post方法

//工行支付前对报文签名
    public static String signICBC(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "INFOSEC_SIGN/1.0");
            conn.setRequestProperty("Content-Length", String.valueOf(param.length()));
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求包
            out.write(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),"GB2312"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }

    //工行发送Post方法
    @Autowired
    FiveFinanceXML fiveFinanceXML;
    public String postICBC(String packageId,String transCode,String xml,Boolean sign,String version,String zip){
        String NCIp = "127.0.0.1";//NC IP地址
        String NCPort = "7070"; //NC 加密端口号
        String NCPort2 = "7080"; //签名端口号
        boolean signatureflg = sign;//是否对交易签名
        String retcertPath = "E:\\admin.crt";//工行公钥 admin.crt所在路径
        String result = "";
        try {
            String sCoding = "GBK";//编码格式
            String cmpVersion = version;//接口版本 0.0.0.1或者0.0.1.0
            String sZip = zip;//是否大文件方式:0,1
            String sLanguage = "zh_CN";//语言
            //下面字段与明文xml包中保持一致
            String sPackageID = packageId;
//            String sPackageID = "PERDIS1240225001352809";//包序列号与xml包中保持一致
            String sTransCode = transCode;//交易代码
            String sBankCode = "102";//银行编码
            String sGroupCIS = "自己填";//集团CIS号
            String sID = "自己填";//证书ID
            String sContent = xml;
            System.out.println(sContent);
            //提交类报文明文xml包
            sContentSign = sContent;
            if (signatureflg) {//需要签名
                java.net.URL aURL = new java.net.URL("http://" + NCIp + ":" + NCPort2);//NCPort2 签名端口号
                java.net.HttpURLConnection urlConnection = (java.net.HttpURLConnection) aURL.openConnection();

                urlConnection.setRequestMethod("POST");
                urlConnection.setDoInput(true);
                urlConnection.setDoOutput(true);
                urlConnection.setUseCaches(false);

                urlConnection.setRequestProperty("Content-Length",String.valueOf(sContentSign.getBytes(sCoding).length));
                urlConnection.setRequestProperty("Content-Type","INFOSEC_SIGN/1.0");
                BufferedOutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
                out.write(sContentSign.getBytes(sCoding));
                out.flush();
                out.close();

                int responseCode = urlConnection.getResponseCode();
                if (responseCode != 200){
                    System.out.println("NC签名失败");
                }

                String resM = urlConnection.getResponseMessage();//NC签名结果

                StringBuffer repContent = new StringBuffer("");
                InputStreamReader in = new InputStreamReader(urlConnection.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(in);

                String readLine = null;
                while ((readLine = bufferedReader.readLine()) != null) {
                    repContent.append(readLine);
                }
                in.close();
                urlConnection.disconnect();

                int beginSign = 0;
                int endSign = 0;
                try{
                    beginSign = repContent.indexOf("<sign>") + 6;
                    endSign = repContent.indexOf("</sign>");
                    System.out.println("repIndx="+beginSign+"&"+endSign);
                }catch(Exception e){
                    System.out.println("!!!!!!!!!!接收签名数据失败,请检查nc设置!!!!!!!!!!");
                }
                String repSignContent = repContent.substring(beginSign, endSign);
                System.out.println("签名内容:"+repSignContent);
                Calendar rightNow = Calendar.getInstance(); //日历的基类
                int year = rightNow.get(Calendar.YEAR);
                int month = rightNow.get(Calendar.MONTH) + 1;
                int date = rightNow.get(Calendar.DAY_OF_MONTH);
                int hour = rightNow.get(Calendar.HOUR_OF_DAY);
                int minute = rightNow.get(Calendar.MINUTE);
                int second = rightNow.get(Calendar.SECOND);
                String sendTime = String.valueOf(year) + String.valueOf(month)
                        + String.valueOf(date) + String.valueOf(hour)
                        + String.valueOf(minute) + String.valueOf(second);
                String urlStr1 = "http://" + NCIp + ":" + NCPort + "/servlet/ICBCCMPAPIReqServlet?PackageID=" + sPackageID + "&SendTime=" + sendTime;

                HttpClient myclient =  HttpClientBuilder.create().build();
                HttpPost mypost = new HttpPost(urlStr1); //加密端口

                mypost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=GBK");
                // 构造post参数
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("Version", cmpVersion));
                params.add(new BasicNameValuePair("TransCode", sTransCode));
                params.add(new BasicNameValuePair("BankCode", sBankCode));
                params.add(new BasicNameValuePair("GroupCIS", sGroupCIS));
                params.add(new BasicNameValuePair("ID", sID));
                params.add(new BasicNameValuePair("PackageID", sPackageID));
                params.add(new BasicNameValuePair("Cert", ""));
                params.add(new BasicNameValuePair("Language", sLanguage));
                params.add(new BasicNameValuePair("zipFlag", sZip));
                params.add(new BasicNameValuePair("reqData", repSignContent));
                // 编码格式转换
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params);
                // 传入请求体
                mypost.setEntity(entity);
                // 发送请求,得到响应体
                HttpResponse response = myclient.execute(mypost);
                System.out.println("开始发送到加密端..."+System.currentTimeMillis());
                int returnFlag = myclient.execute(mypost).getStatusLine().getStatusCode(); //获得http返回码
                System.out.println("已返回数据...");

                try {
                    // 解析数据
                    HttpEntity resEntity = response.getEntity();
                    String postResult = EntityUtils.toString(resEntity);
//                    String postResult = mypost.getResponseBodyAsString();
                    if(postResult.startsWith("reqData=")){
                        postResult = postResult.substring(8);
                    }
                    System.out.println("******************************NC返回******************************\n");
                    System.out.println(new String(postResult));

                    byte[] decodeResult = getFromBASE64(postResult);
                    String sysout = new String(decodeResult, sCoding);

                    int retsign = sysout.indexOf("ICBCCMP");
                    if (retsign != -1){
                        int mLength = Integer.parseInt((sysout.substring(0,10)).trim());
                        String message = sysout.substring(10,10+mLength);
                        String seperator = sysout.substring(10+mLength,10+mLength+7);
                        if (seperator == null || !seperator.equals("ICBCCMP")){
                            System.out.println("返回包分隔符错误");
                        }
                        byte[] crymessage = getFromBASE64(sysout.substring(10+mLength+7));
                    System.out.println("******************************银企互联返回数据******************************\n");
                    System.out.println(sysout);
                    result = sysout;

                } catch (Exception e) {
                    e.printStackTrace();
                }
                mypost.releaseConnection(); //释放http连接
            }
            else {//非提交类交易
                Calendar rightNow = Calendar.getInstance(); //日历的基类
                int year = rightNow.get(Calendar.YEAR);
                int month = rightNow.get(Calendar.MONTH) + 1;
                int date = rightNow.get(Calendar.DAY_OF_MONTH);
                int hour = rightNow.get(Calendar.HOUR_OF_DAY);
                int minute = rightNow.get(Calendar.MINUTE);
                int second = rightNow.get(Calendar.SECOND);
                String sendTime =
                        String.valueOf(year)
                                + String.valueOf(month)
                                + String.valueOf(date)
                                + String.valueOf(hour)
                                + String.valueOf(minute)
                                + String.valueOf(second);

                String urlStr = "http://"+ NCIp + ":" + NCPort + "/servlet/ICBCCMPAPIReqServlet?userId="+sID+"&PackageID=" + sPackageID + "&SendTime=" + sendTime;
                System.out.println("url==" + urlStr);

                HttpClient client = HttpClientBuilder.create().build(); //构建http客户端
                HttpPost post = new HttpPost(urlStr); //构建http post方法
                post.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=GBK");
                // 构造post参数
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("Version", cmpVersion));
                params.add(new BasicNameValuePair("TransCode", sTransCode));
                params.add(new BasicNameValuePair("BankCode", sBankCode));
                params.add(new BasicNameValuePair("GroupCIS", sGroupCIS));
                params.add(new BasicNameValuePair("ID", sID));
                params.add(new BasicNameValuePair("PackageID", sPackageID));
                params.add(new BasicNameValuePair("Cert", ""));
                params.add(new BasicNameValuePair("Language", sLanguage));
                params.add(new BasicNameValuePair("reqData", sContent));
                // 编码格式转换
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params);
                // 传入请求体
                post.setEntity(entity);
                // 发送请求,得到响应体
                HttpResponse response = client.execute(post);
                System.out.println("开始发送。。。");
                int returnFlag = response.getStatusLine().getStatusCode(); //获得http返回码
                System.out.println("发送成功。。。");
                try {
                    // 解析数据
                    HttpEntity resEntity = response.getEntity();
                    String postResult = EntityUtils.toString(resEntity);
//                    String postResult = post.getResponseBodyAsString();

                    System.out.println("******************************NC返回******************************\n");
                    System.out.println(new String(postResult));

                    if(postResult.startsWith("reqData=")){
                        postResult = postResult.substring(8);
                        System.out.println("retMessage==" + new String(postResult));
                        byte[] decodeResult = getFromBASE64(postResult);
                        String sysout = new String(decodeResult,sCoding);
                        System.out.println("******************************银企互联返回数据******************************\n");
                        System.out.println(sysout);
                        return sysout;
                    }else{
                        System.out.println("******************************银企互联返回数据******************************\n");
                        System.out.println(new String(postResult));
                        return new String(postResult);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                post.releaseConnection(); //释放http连接
            }
        } catch (IOException e) {
            e.printStackTrace();
            e.printStackTrace(System.out);
        } catch (Exception e) {
            e.printStackTrace();
            e.printStackTrace(System.out);
            System.err.println("error:" + e.getMessage());
        }
        return result;
    }

4、解密方法

public static byte[] getFromBASE64(String s) {
        if (s == null)
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            return decoder.decodeBuffer(s);
        } catch (Exception e) {
            return null;
            }
        }
       

5、利用dom4j构建报文

//工商银行:多账户余额查询
    public Document queryBanlanceICBC(String account, String packageId,Date date) {
        Document document = DocumentHelper.createDocument();
        document.setXMLEncoding("GBK");
        Element cms = document.addElement("CMS");
        Element eb = cms.addElement("eb");
        Element pub = eb.addElement("pub");
        Element in = eb.addElement("in");
        pub.addElement("TransCode").setText("QACCBAL");
        pub.addElement("CIS").setText(""); //集团CIS编码
        pub.addElement("BankCode").setText("102"); //归属银行编号
        pub.addElement("ID").setText("");
        pub.addElement("TranDate").setText(MyDateUtil.dateToStr1(date));
        pub.addElement("TranTime").setText(MyDateUtil.getDateMS(date));
        pub.addElement("fSeqno").setText(packageId);
        //多账户
        in.addElement("TotalNum").setText("1");//总笔数,必输项
        in.addElement("BLFlag");//是否网银互联账号
        in.addElement("SynFlag");//是否同步返回标志
        Element rd = in.addElement("rd");
        rd.addElement("iSeqno").setText(packageId);//指令顺序号,必输项
        rd.addElement("AccNo").setText(account);//账号,必输项
        rd.addElement("CurrType");//币种
        rd.addElement("ReqReserved3");//行别
        rd.addElement("AcctSeq");//账号序号
        rd.addElement("MainAcctNo");//安心托管主账户
        return document;
    }

6、XML与Map的转化(转载)

//将xml转化为map
    public Map<String, Object> Dom2Map(Document doc){
        Map<String, Object> map = new HashMap<String, Object>();
        if(doc == null)
            return map;
        Element root = doc.getRootElement();
        for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
            Element e = (Element) iterator.next();
            List list = e.elements();
            if(list.size() > 0){
                map.put(e.getName(), Dom2Map(e));
            }else
                map.put(e.getName(), e.getText());
        }
        return map;
    }
    public Map Dom2Map(Element e){
        Map map = new HashMap();
        List list = e.elements();
        if(list.size() > 0){
            for (int i = 0;i < list.size(); i++) {
                Element iter = (Element) list.get(i);
                List mapList = new ArrayList();

                if(iter.elements().size() > 0){
                    Map m = Dom2Map(iter);
                    if(map.get(iter.getName()) != null){
                        Object obj = map.get(iter.getName());
                        if(!obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if(obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    }else
                        map.put(iter.getName(), m);
                }
                else{
                    if(map.get(iter.getName()) != null){
                        Object obj = map.get(iter.getName());
                        if(!obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(iter.getText());
                        }
                        if(obj.getClass().getName().equals("java.util.ArrayList")){
                            mapList = (List) obj;
                            mapList.add(iter.getText());
                        }
                        map.put(iter.getName(), mapList);
                    }else
                        map.put(iter.getName(), iter.getText());
                }
            }
        }else
            map.put(e.getName(), e.getText());
        return map;
    }

7、发送报文

//工行余额查询
    public Map queryBalanceICBC(String account, String userLogin, String uiSref) throws DocumentException {
        String packageId = "2021083644858";
        //发送时间
        Date date = new Date();
        String sendTime = MyDateUtil.dateToStr1(date)+MyDateUtil.getDateMS(date);
        Document document = fiveFinanceXML.queryBanlanceICBC("0200004519000100173", packageId, new Date());
        String transCode = "QACCBAL";
        String xml = document.asXML();
        Boolean sign = false;
        String version = "0.0.1.0";
        String sr = financeHttpPost.postICBC(packageId, transCode, xml, sign, version,"0");
        Document doc = DocumentHelper.parseText(sr);
        Map<String, Object> xmlMap = fiveFinanceXML.Dom2Map(doc);
        Map response = (Map) xmlMap.get("eb");
        Map result = (Map) response.get("out");
        Map resultCode = (Map) response.get("pub");
        Assert.state(resultCode.get("RetCode").equals("0"), (String) resultCode.get("RetMsg"));
        saveResearchICBC(id,userLogin,response);
        return result;
    }

8、结语

第一次做银企直联,大佬轻喷,有错必改!!!!

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 12:18:17  更:2021-09-03 12:19:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年7日历 -2024/7/6 13:06:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码