使用java开发工行银企互联中间件(NC方式)以及一些错误总结

        最近公司上了SAP系统,财务那块需要与工行进行银企直连,由于SAP无法使用socket技术,而工行的签名还必须使用socket技术,所以我们使用Grails开发了工行的银企互联中间件,供SAP调用访问工行数据。

下面是中间件中的主要代码:

 /**

     * @Description 工行银企直连接口
     * @param id  证书ID
     * @param TransCode 交易代码
     * @param BankCode 归属银行编号
     * @param GroupCIS 集团CIS号
     * @param packageId 指令包序列号
     * @param sendTime 请求时间
     * @param Cert  传空
     * @param reqData xml请求字符串
     * @param checkFlag 签名标志 ‘0’ 不需签名; ‘1’需要签名
     * @param version http协议版本号 ‘0.0.1.0’或 ‘0.0.0.1’
     * @return 首先判断是否成功,判定成功后解析xml字符串 。判定是否成功的条件为:返回的字符串中包含“ERRORCODE=”为失败;不包含“ERRORCODE=”为成功
     */
    @WebMethod
    @WebResult
    String send(@WebParam String id,@WebParam String TransCode,@WebParam String BankCode,@WebParam String GroupCIS,@WebParam String packageId,@WebParam String sendTime,@WebParam String Cert,@WebParam String reqData,@WebParam String checkFlag,@WebParam String version)
    {
        println reqData
        println version


        String resultTag=""
        String encoding = "GBK";
        def url="http://192.168.101.110:448/servlet/ICBCCMPAPIReqServlet?userID=${id}&PackageID=${packageId}&SendTime=${sendTime}"
        if("1".equals(checkFlag)){
            reqData=commonService.check(reqData,encoding)
        }


        println reqData
        def responseString=""
        NameValuePair[] params = new NameValuePair[9];
        params[0]=new NameValuePair('Version',version)
        params[1]=new NameValuePair('TransCode',TransCode)
        params[2]=new NameValuePair('BankCode',BankCode)
        params[3]=new NameValuePair('GroupCIS',GroupCIS)
        params[4]=new NameValuePair('PackageID',packageId)
        params[5]=new NameValuePair('Cert',Cert)
        params[6]=new NameValuePair('reqData',reqData)


        params[7]=new NameValuePair('ID',id)
        params[8]=new NameValuePair('Content-Type',"application/x-www-form-urlencoded")


        PostMethod postRequest = new PostMethod(url.trim());


        postRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
        HttpMethodParams p=new HttpMethodParams()
        p.setVersion(HttpVersion.HTTP_1_1)
        postRequest.setParams(p)
        postRequest.setRequestBody(params);
        responseString = commonService.executeMethod(postRequest,encoding);
        if(!responseString ||responseString.toUpperCase().startsWith("ERRORCODE=")){
            resultTag= responseString
        }else{
            responseString = responseString.substring(8,responseString.length())
            resultTag=commonService.getContentFromBASE64(responseString)
        }
        resultTag=resultTag.replaceAll(" ","")
        resultTag=resultTag.replaceAll("\u0000","")
        println resultTag
        return resultTag;

    }


package cn.com.wz


import org.apache.commons.httpclient.Header
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.HttpException
import org.apache.commons.httpclient.SimpleHttpConnectionManager
import org.apache.commons.httpclient.methods.PostMethod


class CommonService {
    /**
     * @Description 执行post方法
     * @param s
     * @return
     * @Create huxx 2014-07-15
     */
    String executeMethod(PostMethod request, String encoding) throws Exception{
        String responseContent = null;
        InputStream responseStream = null;
        BufferedReader rd = null;
        //超时间隔
        int connectTimeOut = 60000;
        //让connectionmanager管理httpclientconnection时是否关闭连接
        boolean alwaysClose = false;
        //返回数据编码格式


        HttpClient client =  new HttpClient(new SimpleHttpConnectionManager(alwaysClose));
        try {
            client.executeMethod(request);
            if(encoding != null){
                responseStream = request.getResponseBodyAsStream();
                rd = new BufferedReader(new InputStreamReader(responseStream,
                        encoding));
                String tempLine = rd.readLine();
                StringBuffer tempStr = new StringBuffer();
                String crlf=System.getProperty("line.separator");
                while (tempLine != null)
                {
                    tempStr.append(tempLine);
                    tempStr.append(crlf);
                    tempLine = rd.readLine();
                }
                responseContent = tempStr.toString();
            }else
                responseContent = request.getResponseBodyAsString();


            Header locationHeader = request.getResponseHeader("location");
            //返回代码为302,301时,表示页面己经重定向,则重新请求location的url,这在
            //一些登录授权取cookie时很重要
            if (locationHeader != null) {
                return "500"


            }
        } catch (HttpException e) {
            throw new Exception(e.getMessage());
        } catch (IOException e) {
            throw new Exception(e.getMessage());


        } finally{
            if(rd != null)
                try {
                    rd.close();
                } catch (IOException e) {
                    throw new Exception(e.getMessage());
                }
            if(responseStream != null)
                try {
                    responseStream.close();
                } catch (IOException e) {
                    throw new Exception(e.getMessage());


                }
        }
        return responseContent;
    }


    /**
     * @Description 使用base64对返回内容解密
     * @param s
     * @return
     * @Create huxx 2014-07-15
     */
    public  String getContentFromBASE64(String s) {
        if (s == null)
            return null;
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
        try {
            def dd=decoder.decodeBuffer(s)
            return new String(dd,"GBK")
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * @Description 对xml包签名
     * @param s
     * @return
     * @Create huxx 2014-07-15
     */
    def check( def reqData,String encoding){
        String result=""
        def path="http://192.168.101.110:449"
        def host="192.168.101.110"
        def port="449"
        Socket socket = new  Socket()
        BufferedReader bufferedReader;
        BufferedWriter bufferedWriter;
        try {
//            def data=URLEncoder.encode(reqData,encoding)
            def data=reqData
//            socket=new  Socket("192.168.101.110",449);// 建立连接,哪个ip,哪个端口号
            SocketAddress dest = new InetSocketAddress("192.168.101.110", 449);


            socket.connect(dest,0);
            socket.setKeepAlive(true)
            // 建立写入流,输出流,向服务器写数据,得到服务器回应
            OutputStream out = socket.getOutputStream();
            OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream(), encoding);


            bufferedWriter = new BufferedWriter(streamWriter);


            bufferedWriter.write("POST " + path + " HTTP/1.1\r\n");
            bufferedWriter.write("Host: " + host + "\r\n");
            println data.length()
            bufferedWriter.write("Content-Length: " + data.length() + "\r\n");
            bufferedWriter.write("Content-Type: INFOSEC_SIGN/1.0\r\n");
            bufferedWriter.write("\r\n");
            bufferedWriter.write(data);
            bufferedWriter.flush();
            def is =socket.getInputStream()


            BufferedInputStream streamReader = new BufferedInputStream(is);
            bufferedReader = new BufferedReader(new InputStreamReader(streamReader, encoding));
            String line = null;
            line = bufferedReader.readLine()
            def flag=0
            while((line!= null))
            {
                if(line.toUpperCase().indexOf("<SIGN>")>=0){
                    flag=1
                }
                if(line.toUpperCase().indexOf("</SIGN>")>=0){
                    flag=0
                    break
                }


                if(flag ==1){
                    result+=line
                }
                line = bufferedReader.readLine()


            }
            System.out.println(result);
            out.close()
            is.close()




        } catch (Exception e) {
            e.printStackTrace();
            e.cause?.printStackTrace()
        } finally {
            try {
                if (socket != null) {
                    socket.close();
                    bufferedReader.close();
                    bufferedWriter.close();
                    socket.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        //判断签名是否成功
        result=result.replace("<sign>","")
        return result
    }
}

使用这几个方法基本就能正常向NC发送数据了。

在使用NC方式时,一个很重要的调试方法是查看NC产生的httpinfo.txt和signinfo.txt两个日志文件。通过日志文件可以查看我们传入的参数是否正确或缺失。

下面是我开发过程中遇到的一些不好理解的问题总结:

一、<RetCode>10385</RetCode><RetMsg>com.icbc.cmp.base.TranFailException:[4066]码制转换错误,网关对前台上送字段转换错</RetMsg>
此错误是由于传到工行的数据不完整或格式不对
我遇到的情况有:
1、post提交时 Version值(0.0.1.0或0.0.0.1)传送错误。(我犯的错误是在Version首字母没有大写,导致Version参数没有传过去 )
2、柜员号前面不能补0。工行给的接口说明中此字段是5位,如果柜员号为12 xml中必须写12 不可以写00012.


二、非账户管家无需上送序号  xml中的AcctSeq(账号序号)不要输入值


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值