1. 获取接口所需要的参数 以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;
	}
  1. 根据接口要求创建报文头的枚举类:发送报文的 字段,名称,长度,必填,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, "");


}
  1. 根据接口要求创建报文体的枚举类
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","女");}},"");
    

}
  1. 构造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());
        }

    }
  1. 发送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;
    }
  1. 解析返回报文
//使用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();
  1. 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发送方式可以使用多线程或者其他框架,如果返回报文通用简洁可以通过通用方法解析 等等。。。