- 获取接口所需要的参数 以map的key value形式
Map<String, String> map = getCustomerInfoMapValue(basicInfo); public Map<String, String> getCustomerInfoMapValue(CustBasicInfo basicInfo) { //终端号//终端IP//获取的是本地的IP地址 map.put("终端IP", SocketUtil.getLocalHostLANAddress().getHostAddress()); //流水号 8 位交易日期+12 位交易序号 String trNum = SocketUtil.getTrNum(basicInfo.getId()); map.put("流水号", trNum); map.put("当前日期时间", getStringDate(new Date(), "yyyy-MM-dd HH:mm:ss")); map.put("当前日期", getStringDate(new Date(), "yyyyMMdd")); map.put("当前时间", getStringDate(new Date(), "HHmmss")); return map; }
- 根据接口要求创建报文头的枚举类:发送报文的 字段,名称,长度,必填,select转换,默认值
public class BaseXmlBeanEnum extends Enum { private static final long serialVersionUID = 6582579870155714449L; // 发送报文 字段,标记,长度,是否必填,select转换,默认值 // 接收报文 字段,标记 private String elementName ; private String elementColumnName ; private String elementLength ; private String elementNotNull ; private Map<String,String> elementOptions ; private String elementDefaultValue ; public BaseXmlBeanEnum(String elementName, String elementColumnName, String elementLength, String elementNotNull, Map<String,String> elementOptions, String elementDefaultValue) { super(elementName); this.elementName = elementName; this.elementColumnName = elementColumnName; this.elementLength = elementLength; this.elementNotNull = elementNotNull; this.elementOptions = elementOptions; this.elementDefaultValue = elementDefaultValue; } public String getElementName() { return elementName; } public void setElementName(String elementName) { this.elementName = elementName; } public String getElementColumnName() { return elementColumnName; } public void setElementColumnName(String elementColumnName) { this.elementColumnName = elementColumnName; } public String getElementLength() { return elementLength; } public void setElementLength(String elementLength) { this.elementLength = elementLength; } public String getElementNotNull() { return elementNotNull; } public void setElementNotNull(String elementNotNull) { this.elementNotNull = elementNotNull; } public Map<String, String> getElementOptions() { return elementOptions; } public void setElementOptions(Map<String, String> elementOptions) { this.elementOptions = elementOptions; } public String getElementDefaultValue() { return elementDefaultValue; } public void setElementDefaultValue(String elementDefaultValue) { this.elementDefaultValue = elementDefaultValue; } } public class Socket_Head extends BaseXmlBeanEnum { private static final long serialVersionUID = 795381566820679308L; public Socket_Head(String elementName, String elementColumnName, String elementLength, String elementNotNull, Map<String, String> elementOptions, String elementDefaultValue) { super(elementName, elementColumnName, elementLength, elementNotNull, elementOptions, elementDefaultValue); } public static List<BaseXmlBeanEnum> getAllElement() { List<BaseXmlBeanEnum> list = null; try { list = BaseXmlBeanEnum.getEnumList(Socket_Head.class); }catch (Exception e){ } return list; } public static BaseXmlBeanEnum getElementByName(String elementName) throws Exception{ BaseXmlBeanEnum baseXmlBeanEnum = (BaseXmlBeanEnum) BaseXmlBeanEnum.getEnum(BaseXmlBeanEnum.class, elementName); return baseXmlBeanEnum; } public static final BaseXmlBeanEnum TrCode = new Socket_Head("TrCode", "交易码", "6", "1", null, ""); public static final BaseXmlBeanEnum TermId = new Socket_Head("TermId", "终端IP", "20", "1", null, ""); public static final BaseXmlBeanEnum TermDateTime = new Socket_Head("TermDateTime", "当前日期时间", "20", "1", null, ""); public static final BaseXmlBeanEnum TermIP = new Socket_Head("TermIP", "终端IP", "20", "1", null, ""); public static final BaseXmlBeanEnum SndDate = new Socket_Head("SndDate", "当前日期", "8", "1", null, ""); public static final BaseXmlBeanEnum SndTime = new Socket_Head("SndTime", "当前时间", "6", "1", null, ""); public static final BaseXmlBeanEnum Memo = new Socket_Head("Memo", "保留", "100", "0", null, ""); public static final BaseXmlBeanEnum RetCode = new Socket_Head("RetCode", "返回码", "6", "0", null, ""); public static final BaseXmlBeanEnum Desc = new Socket_Head("Desc", "错误信息", "60", "0", null, ""); }
- 根据接口要求创建报文体的枚举类
public class Socket_015001_1 extends BaseXmlBeanEnum { public Socket_015001_1(String elementName, String elementColumnName, String elementLength, String elementNotNull, Map<String, String> elementOptions, String elementDefaultValue) { super(elementName, elementColumnName, elementLength, elementNotNull, elementOptions, elementDefaultValue); } public static List<BaseXmlBeanEnum> getAllElement() { List<BaseXmlBeanEnum> list = null; try { list = BaseXmlBeanEnum.getEnumList(Socket_015001_1.class); }catch (Exception e){ } return list; } public static String getSocketCode() { return Socket_015001_1.class.getName().split("_")[1]; } public static BaseXmlBeanEnum getElementByName(String elementName) throws Exception{ BaseXmlBeanEnum baseXmlBeanEnum = (BaseXmlBeanEnum) BaseXmlBeanEnum.getEnum(BaseXmlBeanEnum.class, elementName); return baseXmlBeanEnum; } public static final BaseXmlBeanEnum customername = new Socket_015001_1("customername","基本信息客户名称","60","1",null,""); public static final BaseXmlBeanEnum certificatestype = new Socket_015001_1("certificatestype","基本信息证件类型","1","1", new HashMap<String, String>(){{put("1","01");put("2","08");put("3","03");put("4","02");put("5","07");put("6","04");put("7","05");put("8","09");put("9","10");put("10","06");put("11","99");}},"01"); public static final BaseXmlBeanEnum idnumber = new Socket_015001_1("idnumber","基本信息证件号码","18","1",null,""); public static final BaseXmlBeanEnum mobile = new Socket_015001_1("mobile","基本信息手机","20","1",null,""); public static final BaseXmlBeanEnum address = new Socket_015001_1("address","基本信息详细地址","100","1",null,""); public static final BaseXmlBeanEnum postcode = new Socket_015001_1("postcode","基本信息邮政编码","6","0",null,""); public static final BaseXmlBeanEnum sex = new Socket_015001_1("sex","基本信息性别","2","1", new HashMap<String, String>(){{put("1","男");put("2","女");}},""); }
- 构造socket xml报文
//根据对象 和 数据 拼装xml报文 public static String getSocketXml(String socketCode, List<BaseXmlBeanEnum> bodyList, Map<String, String> map, String macKey) throws Exception { try{ map.put("交易码",socketCode); Element transactionElement = DocumentHelper.createElement("transaction"); Document doc = DocumentHelper.createDocument(transactionElement); doc.setXMLEncoding("GBK"); Element headElement = transactionElement.addElement("head"); Element bodyElement = transactionElement.addElement("body"); Element requestElement = bodyElement.addElement("request"); /*报文头*/ List<BaseXmlBeanEnum> headList = Socket_Head.getAllElement(); addXmlElement(headList, map, headElement); /*报文体*/ addXmlElement(bodyList, map, requestElement); /*报文签名处理*/ Element signatureElement = transactionElement.addElement("signature"); signatureElement.addText(getMac(bodyElement.asXML(),macKey)); String xml = doc.asXML(); return getSendXml(xml); }catch (Exception e){ e.printStackTrace(); throw new Exception(e.getMessage()); } } private static void addXmlElement(List<BaseXmlBeanEnum> list, Map<String,String> map, Element parentElement) throws Exception { try { Element element ; String value; //报文体 for (BaseXmlBeanEnum xmlBean : list) { value = MapUtils.getString(map,xmlBean.getElementColumnName()); //转换options if(MapUtils.isNotEmpty(xmlBean.getElementOptions())&& StringUtils.isNotBlank(value)){ value = MapUtils.getString(xmlBean.getElementOptions(),value,value); } //默认值 if(StringUtils.isBlank(value)&&StringUtils.isNotBlank(xmlBean.getElementDefaultValue())){ value = xmlBean.getElementDefaultValue(); } //是否可为空 if(xmlBean.getElementNotNull().equals("1")&&StringUtils.isBlank(value)){ throw new Exception(xmlBean.getElementColumnName()+",不允许为空"); } //长度截取 if(StringUtils.isNotBlank(value)){ int eLength = Integer.parseInt(xmlBean.getElementLength()); byte[] bytes = value.getBytes("GBK"); if(bytes.length>eLength){ if(eLength>value.length()){ eLength = value.length()/2; } value = value.substring(0,eLength); } }else{ value = ""; } element = DocumentHelper.createElement(xmlBean.getElementName()); element.addText(value); parentElement.add(element); } }catch (Exception e){ e.printStackTrace(); throw new Exception("封装请求报文出错:"+e.getMessage()); } }
- 发送socet报文
public static synchronized String socketPost(String clientIp, String clientPort, String xml, String filePath) throws Exception { String rs = ""; if(clientIp==null||"".equals(clientIp)||clientPort==null||"".equals(clientPort)){ throw new Exception("数据同步地址信息有误,请联系管理员!"); } int clientPortInt = Integer.parseInt(clientPort); // logger.info("clientIp:"+clientIp+" clientPort:"+clientPort); Socket s = null; OutputStream out = null; InputStream in = null; try { s = new Socket(clientIp, clientPortInt); s.setSendBufferSize(8192); s.setReceiveBufferSize(8192); s.setTcpNoDelay(true); s.setSoTimeout(60*1000); s.setKeepAlive(true); out = s.getOutputStream(); in = s.getInputStream(); out.write(xml.getBytes("GBK")); out.flush(); if (in.available()>0){ Thread.sleep(100); } //前8字节报文长度 byte[] byte8 = new byte[8]; in.read(byte8); logger.info("===========================前8字节报文长度"+new String(byte8)); Integer int8 = Integer.parseInt(new String(byte8,"GBK")); logger.info("==========================="+int8); //报文正文 byte[] byteXml = new byte[int8]; //读取字节流不推荐下面这种一次性全部读取方式,受网络传输和大小的影响可能读取不全 in.read(byteXml); rs = new String(byteXml, "GBK"); logger.info("===========================报文正文"+rs); } catch (Exception e) { e.printStackTrace(); throw new Exception("socketPost发送请求异常:"+e.getMessage()); }finally{ try { if(out!=null){ out.close(); } if(in!=null){ in.close(); } if(s!=null){ s.close(); } } catch (IOException e) { } } return rs; } /** * 读取输入流 * @param in * @return */ private static byte[] readStream(InputStream in,int length) throws Exception { if(in==null){ return null; } byte[] b = null; ByteArrayOutputStream outSteam = null; try { byte[] buffer = new byte[1024]; outSteam = new ByteArrayOutputStream(); int len = -1; int readLen = 0; while ((len = in.read(buffer)) != -1) { if((readLen+len)>length){ len = length-readLen; outSteam.write(buffer, 0, len); break; }else{ readLen += len; outSteam.write(buffer, 0, len); } } b = outSteam.toByteArray(); } catch (IOException e) { throw new Exception("读取流信息异常:"+e.getMessage()); } finally{ try { if(outSteam!=null){ outSteam.close(); outSteam = null; } if(in!=null){ in.close(); in = null; } } catch (IOException e) { } } return b; }
- 解析返回报文
//使用Document document = DocumentHelper.parseText(returnMassage);将返回的xml转换成Document对象 进行后续处理 String RetCode = document_015001.getRootElement().element("head").element("RetCode").getText(); String Desc = document_015001.getRootElement().element("head").element("Desc").getText();
-
socket读取文件
//30位文件名 byte[] byte30 = new byte[30]; in.read(byte30); String fileName = new String(byte30, "GBK").trim(); if(StringUtils.isBlank(fileName)){ fileName = UUID.randomUUID().toString()+".jpg"; } logger.info("==========================="+fileName); //前8字节文件长度 byte8 = new byte[8]; in.read(byte8); int8 = Integer.parseInt(new String(byte8,"GBK")); logger.info("==========================="+int8); //文件 byte[] byteFile = readStream(in,int8); //本地文件 File fileDir = new File(filePath); if(!fileDir.exists()||!fileDir.isDirectory()) { fileDir.mkdirs(); } File file = new File(filePath + File.separatorChar + fileName); FileOutputStream fos = new FileOutputStream(file); fos.write(byteFile); fos.flush(); fos.close();
我这里只列举我业务场景的socket处理过程,当然也可以简化或者配置化,比如:报文模版(报文头、报文体)通过数据库维护,socket发送方式可以使用多线程或者其他框架,如果返回报文通用简洁可以通过通用方法解析 等等。。。