123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- package com.hcloud.microserver.bank.util;
- import com.alibaba.fastjson.JSONObject;
- import com.hcloud.microserver.bank.bo.BankLoginUserRespBO;
- import com.hcloud.microserver.bank.bo.BankQueryBaseParam;
- import com.hcloud.microserver.bank.bo.BankResponseBase;
- import com.hcloud.microserver.commoncore.util.string.StringUtils;
- import lombok.Data;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.httpclient.HttpClient;
- import org.apache.commons.httpclient.HttpStatus;
- import org.apache.commons.httpclient.methods.PostMethod;
- import org.dom4j.DocumentException;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.core.ValueOperations;
- import org.springframework.stereotype.Component;
- import java.io.*;
- import java.net.Socket;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- @Slf4j
- @Data
- @Component
- public class BankUtil {
- private final static SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
- private String charset="gb2312";
- @Value("${cqrcb.bank.sign.ip}")
- private String ipSign;
- @Value("${cqrcb.bank.sign.port}")
- private int portSign;
- @Value("${cqrcb.bank.sslclient.ip}")
- private String ip;
- @Value("${cqrcb.bank.sslclient.port}")
- private int port;
- @Autowired
- private RedisTemplate redisTemplate;
- /**
- * 根据传入实体进行业务接口对接
- * @param param
- * @param type 0 为不签名 1 为签名
- * @param clazz
- * @return
- */
- public BankResponseBase bankRequst(BankQueryBaseParam param, int type,Class<? extends BankResponseBase> clazz) {
- if (param==null||param.getData()==null){
- return null;
- }
- Object paramData = param.getData();
- Map<String,Object> reqParam= new HashMap<>();
- reqParam.put("ReqParam",paramData);
- Map<String,Object> opReq = new HashMap<>();
- opReq.put("opReq",reqParam);
- Map<String,Object> CQRCBBankData = new HashMap<>();
- CQRCBBankData.put("CQRCBBankData",opReq);
- try {
- if (type ==1){
- String s = packSignXml(paramData);
- opReq.put("signData",s);
- }
- Object o = JSONObject.toJSON(CQRCBBankData);
- RemoveNullAttr re = new RemoveNullAttr();
- Object o1 = re.traverseJson(o);
- String s = JsonAndXmlUtils.jsonToPrettyXml((JSONObject)o1);
- String url1 = "http://"+ip+":"+port+"/corporLink";
- String h = param.getSessionId()+"|"+param.getServiceId()+"|"+param.getSerialNo()+"|"+param.getReqTime()+"|#";
- log.info("request cqcrb url:"+url1);
- log.info(param.getServiceId()+" request cqcrb content:"+h+s);
- String resp = sendPost(url1, h + s);
- log.info("cqcrb response content:"+resp);
- return xmlStringToEntity(resp,clazz);
- // return resp;
- }catch (Exception e){
- log.info("fail to request "+param.getServiceId()+"{}",paramData);
- }
- return null;
- }
- /**
- * 解析xml文件维对应的实体
- * @param xmlString
- * @param clazz
- * @return
- */
- public BankResponseBase xmlStringToEntity(String xmlString,Class<? extends BankResponseBase> clazz) throws Exception {
- if (StringUtils.isEmpty(xmlString)){
- return null;
- }
- String [] split;
- if (xmlString.contains("|#")){
- String name = clazz.getName();
- BankResponseBase responseBase = clazz.newInstance();
- String headString = xmlString.substring(0, xmlString.lastIndexOf("|#"));
- String xml = xmlString.substring(xmlString.lastIndexOf("|#")+2);
- split = headString.split("\\|");
- int length = split.length;
- if (length <3){
- return null;
- }
- JSONObject jsonObject = JsonAndXmlUtils.xmlToJson(xml);
- log.info(xml);
- if (jsonObject.containsKey("CQRCBBankData")){
- JSONObject CQRCBBankDataJSON = (JSONObject) jsonObject.get("CQRCBBankData");
- if (CQRCBBankDataJSON.containsKey("opRep")){
- JSONObject opRepJSON = (JSONObject) CQRCBBankDataJSON.get("opRep");
- if (opRepJSON.containsKey("opResult")){
- Object opResultObject = opRepJSON.get("opResult");
- // net.sf.json.JSONObject jsonObject1 = net.sf.json.JSONObject.fromObject(opResultObject);
- // responseBase = (BankResponseBase) net.sf.json.JSONObject.toBean(jsonObject1, clazz);
- responseBase = JSONObject.parseObject(JSONObject.toJSONString(opResultObject), clazz);
- responseBase.setSessionId(split[0]);
- responseBase.setSerialNo(split[1]);
- responseBase.setRetCode(split[2]);
- if (length > 3){
- responseBase.setErrorMsg(split[3]);
- }
- }
- }
- }
- return responseBase;
- }
- return null;
- }
- /**
- * 发送xml请求到server端
- * @param url xml请求数据地址
- * @param xmlString 发送的xml数据流
- * @return null发送失败,否则返回响应内容
- */
- public String sendPost(String url,String xmlString){
- //创建httpclient工具对象
- HttpClient client = new HttpClient();
- //创建post请求方法
- PostMethod myPost = new PostMethod(url);
- //设置请求超时时间
- // client.setConnectionTimeout(3000*1000);
- String responseString = null;
- try{
- //设置请求头部类型
- myPost.setRequestHeader("Content-Type","text/xml;charset=utf-8");
- //设置请求体,即xml文本内容,一种是直接获取xml内容字符串,一种是读取xml文件以流的形式
- myPost.setRequestBody(xmlString);
- int statusCode = client.executeMethod(myPost);
- //只有请求成功200了,才做处理
- if(statusCode == HttpStatus.SC_OK){
- InputStream inputStream = myPost.getResponseBodyAsStream();
- // BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
- // StringBuffer stringBuffer = new StringBuffer();
- // String str = "";
- // while ((str = br.readLine()) != null) {
- // stringBuffer.append(str);
- // }
- // responseString = stringBuffer.toString();
- responseString = convertStreamToString(inputStream);
- }
- }catch (Exception e) {
- e.printStackTrace();
- }finally{
- myPost.releaseConnection();
- }
- return responseString;
- }
- public String convertStreamToString(InputStream is) {
- StringBuilder sb1 = new StringBuilder();
- byte[] bytes = new byte[4096];
- int size = 0;
- try {
- while ((size = is.read(bytes)) > 0) {
- String str = new String(bytes, 0, size, "UTF-8");
- sb1.append(str);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return sb1.toString();
- }
- /**
- * 1. sessionId为会话编号,每次登录之后会产生一个唯一的编号,用于标识这次会话。用户每次进行交易时都必须上送该Id。如果是登录交易,则请求报文头中的sessionId传-1即可。
- * 2. serviceId为服务编号,用以区分不同的操作,见具体交易格式说明,如登录交易的服务编号为: CL0001。
- * 3. serialNo为交易序列号,客户端唯一标识,返回时原样返回。
- * 4. reqTime为请求时间,yyyyMMddHHmmss。
- * 5. retCode和errorMsg为响应代码和错误信息,请求处理成功时,返回代码为’00000000’,错误信息留空;其它情况均视为请求处理失败。
- * 6. 请求报文体和响应报文体为XML格式,封装了具体的交易数据,格式请参见下一章节描述。
- * 7. 对于登录和转账等交易,请求报文体需要进行签名。
- * 8. 登录后,企业客户如果在设定时间之内没有进行任何请求,该会话将被自动清理,需要重新登录后才可以进行一般交易请求。(目前暂定:设置超时时间为12小时)
- * 9. 如果sessionId对应的会话是超时或者非法的时候,服务端只会返回响应报文头“-1|EBLN0000|会话已超时,请重新登录|#”,不会返回报文体。
- * 10. 如果请求的XML包格式不正确,或者opName指定的交易名称不正确时,服务器端也只会返回响应报文头,不会返回报文体。
- * @param sessionId
- * @param serviceId
- * @return
- */
- public String getRequestUrl(String ip,int port,String sessionId,String serviceId,String serialNo){
- String url = "http://"+ip+":"+port;
- return url;
- }
- public String getTime(Date date){
- return format.format(date);
- }
- public String sendSignRequestTCP(String oriData) {
- StringBuffer sb = new StringBuffer("");
- Socket socket = null;
- BufferedInputStream in = null;
- BufferedOutputStream out = null;
- log.info("sign ip:"+ipSign);
- log.info("sign port:"+portSign);
- log.info("sign content:"+oriData);
- try {
- int length = oriData.getBytes(charset).length;
- byte[] buf = new byte[length + 5];
- String lenValue = String.valueOf(length);
- System.arraycopy(oriData.getBytes(charset), 0, buf, 5, length);
- for (int i = 0; i < 5; i++)
- buf[i] = '0';
- int idx = 0;
- for (int i = 5 - lenValue.length(); i < 5; i++) {
- buf[i] = (byte) lenValue.charAt(idx++);
- }
- socket = new Socket(ipSign, portSign);
- out = new BufferedOutputStream(socket.getOutputStream());
- out.write(buf);
- out.flush();
- in = new BufferedInputStream(socket.getInputStream());
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = in.read(buffer)) != -1) {
- sb.append(new String(buffer, 0, len, charset));
- }
- } catch (Exception e) {
- sb = new StringBuffer("-1");
- e.printStackTrace();
- } finally {
- try {
- if (null != socket) {
- socket.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- try {
- if (out != null)
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- try {
- if (in != null)
- in.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return sb.toString();
- }
- /**
- * <msg>
- * <msg_head>
- * <msg_type>0</msg_type>
- * <msg_id>1005</msg_id>
- * <msg_sn>0</msg_sn>
- * <version>1</version>
- * </msg_head>
- * <msg_body>
- * <origin_data_len>签名原文的长度</origin_data_len>
- * <origin_data>签名原文</origin_data>
- * </msg_body>
- * </msg>
- * @param paramData
- * @return
- */
- public String packSignXml(Object paramData) throws Exception {
- if (paramData == null){
- return null;
- }
- JSONObject si = new JSONObject();
- si.put("ReqParam",JSONObject.toJSON(paramData));
- String sJson = JsonAndXmlUtils.JsonToXml((JSONObject) JSONObject.parse(JSONObject.toJSONString(si)));
- String substring = sJson.substring(sJson.lastIndexOf("<ReqParam>"));
- log.info("签名后的数据:"+substring);
- JSONObject head =new JSONObject();
- head.put("msg_type",0);
- head.put("msg_id",1005);
- head.put("msg_sn",0);
- head.put("version",1);
- JSONObject body = new JSONObject();
- body.put("origin_data_len",substring.length());
- body.put("origin_data","dataDataJxml");
- JSONObject msg = new JSONObject();
- msg.put("msg_head",head);
- msg.put("msg_body",body);
- JSONObject req = new JSONObject();
- req.put("msg",msg);
- String s = JsonAndXmlUtils.JsonToXml(req);
- String dataDataJxml = s.replace("dataDataJxml", substring);
- String s1 = sendSignRequestTCP(dataDataJxml);
- String s2 = xmlToSignData(s1);
- log.info("sign return data :"+s1);
- log.info("data sign content :"+s2);
- return s2;
- }
- public String xmlToSignData(String xmlString) throws DocumentException {
- JSONObject jsonObject = JsonAndXmlUtils.xmlToJson(xmlString);
- if (jsonObject.containsKey("msg")){
- JSONObject msg = (JSONObject)jsonObject.get("msg");
- if (msg.containsKey("msg_body")){
- JSONObject msg_body = (JSONObject)msg.get("msg_body");
- if (msg_body.containsKey("signed_data")){
- String signed_data = msg_body.get("signed_data").toString();
- return replaceBlank(signed_data);
- }
- }
- }
- return null;
- }
- public String replaceBlank(String str) {
- String dest = "";
- if (str!=null) {
- Pattern p = Pattern.compile("\\s*|\t|\r|\n");
- Matcher m = p.matcher(str);
- dest = m.replaceAll("");
- }
- return dest;
- }
- public void cacheLoginSession(BankLoginUserRespBO bankLoginUserRespBO){
- ValueOperations ops = redisTemplate.opsForValue();
- ops.set("cqcarbon.bank.user.sessionId",bankLoginUserRespBO,12*3600, TimeUnit.SECONDS);
- }
- public BankLoginUserRespBO getLoginSession(){
- ValueOperations ops = redisTemplate.opsForValue();
- BankLoginUserRespBO o = (BankLoginUserRespBO)ops.get("cqcarbon.bank.user.sessionId");
- if (o != null){
- return o;
- }
- return null;
- }
- }
|