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 list = new ArrayList();
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());
}
}
}
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() + "]";
}
}
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
}
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
}
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 + "]";
}
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[]{"",""};//需要去除的标签
//setter getter
public String[] getOutString() {
return outString;
}
@Override
public String toString() {
return "Result [error_code=" + errorCode + ", error_msg=" + errorMsg
+ ", outString=" + Arrays.toString(outString) + "]";
}
}
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;
//setter getter
}
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;
}
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 头文件
/**
* 解析消息内容
*
* @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 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();
}
}