1. 程式人生 > >spring boot 介面 XML 接受和請求(傳送篇)

spring boot 介面 XML 接受和請求(傳送篇)

業務處理類


import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import com.aliyun.openservices.shade.com.alibaba.rocketmq.shade.com.alibaba.fastjson.JSON;
import com.xianjinxia.app.domain.Vendor;
import com.xianjinxia.sms.SMSConstants;
import com.xianjinxia.sms.pojo.input.MessagePojo;
import com.xianjinxia.sms.pojo.output.SmsResultPojo;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.Body;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.Dest;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.Dests;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.Head;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.Result;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.XmlDto;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.util.CloudFengUtil;

/**
 * Created by admin on 2017/5/16.
 */
@Service
public class CloudFengSendService {

    private Logger log = Logger.getLogger(CloudFengSendService.class);

    public SmsResultPojo sendMessageCommon(MessagePojo messagePojo, Vendor vendor) {

        String requestXmlStr = getRequestXmlStr(messagePojo, vendor);

        String result = null;
        try {
        	log.info("出口引數="+JSON.toJSONString(requestXmlStr));
            result = CloudFengUtil.doPost(vendor.getUrl(), requestXmlStr);
            log.info("返回result引數="+JSON.toJSONString(new String(result.getBytes(),"UTF-8")));
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        log.info("sendSms-result:" + result);
        if (null != result) {
            Result heads = new Result();
            for (String str : heads.getOutString()) {
                result = result.replace(str, "");
            }
        }
        Result res = (Result) CloudFengUtil.readMessage(Result.class, result);
        log.info("返回res引數="+JSON.toJSONString(res));
        return getSmsResultPojo(res);
    }

    private String getRequestXmlStr(MessagePojo messagePojo, Vendor vendor) {
        String timeStamp = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        XmlDto xmlDto = new XmlDto();
        Head head = new Head();
        head.setAppKey(vendor.getAppKey());
        head.setNonceStr(vendor.getUsername());
        head.setSign("");
        head.setTimeStamp(timeStamp);
        List<Dest> list = new ArrayList<Dest>();
        for (String tel : messagePojo.getTelephone().split(",")) {
            Dest dest = new Dest();
            dest.setDestId(tel);
            dest.setMissionNum("verify_code" + timeStamp);
            list.add(dest);
        }
        Dests ds = new Dests();
        ds.setDest(list);
        Body body = new Body();
        body.setBatchNum(vendor.getUsername() + timeStamp);
        body.setDests(ds);
        body.setContent(messagePojo.getMsgContent());
        body.setSmsType("verify_code");
        xmlDto.setHead(head);
        xmlDto.setBody(body);

        String smsXml = CloudFengUtil.sortString(xmlDto, vendor.getAppSecret());
        log.info("md5-befor:" + smsXml);
        String smsSign = CloudFengUtil.MD5(String.valueOf(smsXml));
        log.info("md5-after:" + smsSign);
        xmlDto.getHead().setSign(smsSign);
        String requestXml = CloudFengUtil.bulidMessage(xmlDto);
        log.info("sendsms:" + requestXml);
        return requestXml;
    }

    private SmsResultPojo getSmsResultPojo(Result result) {
        if (result == null) {
            return null;
        }
        if (CloudFengUtil.CODE_SUCCESS.equals(result.getErrorCode())) {
            return new SmsResultPojo().setVendorCode(result.getErrorCode());
        } else {
            return new SmsResultPojo(SMSConstants.SMS_CODE_FAILURE,SMSConstants.SMS_CODE_FAILURE_MSG).setVendorCode(result.getErrorCode());
        }
    }

}

XMLDto

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"head","body"})
@XmlRootElement(name="xml")
public class XmlDto {
	private Head head;
	private Body body;
	
//setter getter
	@Override
	public String toString() {
		return "XmlDto [body=" + body + ", head=" + head + ", getBody()="
				+ getBody() + ", getHead()=" + getHead() + ", getClass()="
				+ getClass() + ", hashCode()=" + hashCode() + ", toString()="
				+ super.toString() + "]";
	}
}

Body


import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="xml")
public class Body {
	@XmlElement(name = "dests")
	private Dests dests;
	@XmlElement(name = "batch_num")
	private String batchNum;
	@XmlElement(name = "sms_type")
	private String smsType;
	@XmlElement(name = "content")
	private String content;

//setter  getter

}

Head


import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="xml")
public class Head {
	@XmlElement(name = "app_key")
	private String appKey;
	@XmlElement(name = "time_stamp")
	private String timeStamp;
	@XmlElement(name = "nonce_str")
	private String nonceStr;
	@XmlElement(name = "sign")
	private String sign;
// setter  getter
}

SMSDto


public class SmsDto {
	
	private String app_key;		//在簡訊使用者後臺獲取或者與管理員聯絡
	private String time_stamp;	//格式為yyyyMMddHHmmss
	private String nonce_str;	//簡訊平臺使用者名稱
	private String sign;		
	
	private String batch_num;	//批次號,不能重複
	private String mission_num;	//任務號
	private String dest_id;		//接收手機
	private String content;		//簡訊內容
	private String sms_type;	//簡訊型別 verify_code:驗證碼  notice:通知  advert:營銷類
	
// setter getter	

	@Override
	public String toString() {
		return "SmsDto [app_key=" + app_key + ", batch_num=" + batch_num
				+ ", content=" + content + ", dest_id=" + dest_id
				+ ", mission_num=" + mission_num + ", nonce_str=" + nonce_str
				+ ", sign=" + sign + ", sms_type=" + sms_type + ", time_stamp="
				+ time_stamp + "]";
	}

result


import java.io.Serializable;
import java.util.Arrays;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="xml")
public class Result implements Serializable {

	@XmlElement(name = "error_code")
	private String errorCode;
	@XmlElement(name = "error_msg")
	private String errorMsg;
	@XmlTransient
	private String outString[] = new String[]{"<head>","</head>"};//需要去除的標籤


//setter getter

	public String[] getOutString() {
		return outString;
	}
	@Override
	public String toString() {
		return "Result [error_code=" + errorCode + ", error_msg=" + errorMsg
				+ ", outString=" + Arrays.toString(outString) + "]";
	}
	
}

 Dests

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"dest"})
@XmlRootElement(name="xml")
public class Dests {
	private List<Dest> dest;
//setter  getter
}

Dest

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="xml")
public class Dest {
	@XmlElement(name = "mission_num")
	private String missionNum;
	@XmlElement(name = "dest_id")
	private String destId;
}

CloudFengUtil  類


import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.Dest;
import com.xianjinxia.sms.service.impl.cloudfeng.sms.dto.XmlDto;

public class CloudFengUtil {

    private static final Logger log = LoggerFactory.getLogger(CloudFengUtil.class);
    public static final String CODE_SUCCESS = "000000";
    private static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";//xml 標頭檔案

    /**
     * 解析訊息內容
     *
     * @param objClass
     * @param msg
     * @return
     */
    public static Object readMessage(Class objClass, String msg) {
        try {
            JAXBContext jc = JAXBContext.newInstance(objClass);
            Unmarshaller u = jc.createUnmarshaller();
            return objClass.cast(u.unmarshal(new StringReader(msg)));
        } catch (JAXBException e) {
            e.printStackTrace();
            log.error("解析訊息出錯", e.getMessage());
        }
        return null;
    }

    /**
     * 生成內容
     *
     * @param mesgBean
     * @return string
     */
    public static String bulidMessage(Object mesgBean) {
        Marshaller marshaller;
        try {
            JAXBContext jc = JAXBContext.newInstance(mesgBean.getClass());
            marshaller = jc.createMarshaller();
            marshaller.setProperty("jaxb.encoding", "UTF-8");
            marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);

            marshaller.setProperty("jaxb.fragment", Boolean.TRUE);

            marshaller.setProperty("com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler", (CharacterEscapeHandler) (ch, start, length, isAttVal, writer) -> writer.write(ch, start, length));
            StringWriter ws = new StringWriter();
            marshaller.marshal(mesgBean, ws);
            return XML_HEAD + ws.toString();
        } catch (JAXBException e) {
            log.error("生成訊息出現錯誤: [{}]", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析內容
     *
     * @param clazz
     * @param xmlStr
     * @return
     */
    public static Object convertXmlStrToObject(Class clazz, String xmlStr) {
        Object xmlObject = null;
        try {
            JAXBContext context = JAXBContext.newInstance(clazz);
            // 進行將Xml轉成物件的核心介面  
            Unmarshaller unmarshaller = context.createUnmarshaller();
            StringReader sr = new StringReader(xmlStr);
            xmlObject = unmarshaller.unmarshal(sr);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return xmlObject;
    }


    /**
     * 排序
     *
     * @param xmlDto
     * @return
     */
    public static String sortString(XmlDto xmlDto, String appSecret) {
        if (null != xmlDto) {
            StringBuilder sb = new StringBuilder();
            sb.append("app_key=").append(xmlDto.getHead().getAppKey()).append("&batch_num=")
                    .append(xmlDto.getBody().getBatchNum()).append("&content=").append(xmlDto.getBody().getContent());
            List<Dest> list = xmlDto.getBody().getDests().getDest();
            StringBuilder builder = new StringBuilder();
            for (Dest d : list) {
                builder.append("&dest_id=").append(d.getDestId());
            }
            for (Dest d : list) {
                builder.append("&mission_num=").append(d.getMissionNum());
            }
            sb.append(builder).append("&nonce_str=").append(xmlDto.getHead().getNonceStr()).append("&sms_type=")
                    .append(xmlDto.getBody().getSmsType()).append("&time_stamp=")
                    .append(xmlDto.getHead().getTimeStamp()).append("&app_secret=").append(appSecret);
            return sb.toString();
        }
        return null;
    }

    /**
     * MD5 32位 小寫
     */
    public static String MD5(String param) {
        try {
            byte[] byteArray = param.getBytes("utf-8");
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] md5Bytes = md5.digest(byteArray);
            StringBuilder builder = new StringBuilder();
            for (byte md5Byte : md5Bytes) {
                int val = ((int) md5Byte) & 0xff;
                if (val < 16) {
                    builder.append("0");
                }
                builder.append(Integer.toHexString(val));
            }
            return builder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String doPost(String url, String params) throws IOException {
        CloseableHttpResponse response = null;
        // 獲取預設的httpclient
        try (CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(getRequestConfig()).build()) {
            StringEntity entity = new StringEntity(params, "utf-8");
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "text/xml;charset=utf-8");
            httpPost.setEntity(entity);
            // 執行http請求,獲取response
            response = client.execute(httpPost);
            if (response == null) {
                return null;
            }
            return EntityUtils.toString(response.getEntity());
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

    private static RequestConfig getRequestConfig() {
        return RequestConfig.custom()
                .setConnectionRequestTimeout(5000)   //從連線處獲取連線的 timeout
                .setConnectTimeout(20000)               //傳送http請求 連線目標伺服器的timeout
                .setSocketTimeout(60000)                //獲取目標伺服器資料的timeout
                .build();
    }
}