Authored by DengXinFei

更新短信运营商

... ... @@ -101,7 +101,8 @@ public class SMSSendHelper {
String beanName = SmsProviderCodeEnum.getBeanNameByValue(smsProviderCode);
if (StringUtils.isEmpty(beanName)) {
// 默认玄武
beanName = "XWSendSMSServiceImpl";
//beanName = "XWSendSMSServiceImpl";
beanName = "YTSendSMSServiceImpl";
}
ISendSMSService sms = SpringContextUtil.getBean(beanName, ISendSMSService.class);
return sms.sendSMS(mobileList, content, params);
... ...
package com.yoho.yhmessage.sms.service.impl;
import com.yoho.yhmessage.sms.service.ISendSMSService;
import com.yoho.yhmessage.sms.service.model.Response;
import com.yoho.yhmessage.sms.service.model.SendNoticeResultBean;
import com.yoho.yhmessage.sms.util.HttpUtils;
import com.yoho.yhmessage.sms.util.PhoneUtil;
import com.yoho.yhmessage.sms.util.StringUtil;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 上海移通短信发送实现
* @remark 默认使用移通进行短信发送
*
*
* @ClassName YTSendSMSServiceImpl
* @Author xinfei
* @Date 2018/7/30 11:38
**/
@Service("YTSendSMSServiceImpl")
public class YTSendSMSServiceImpl implements ISendSMSService {
static Logger logger = LoggerFactory.getLogger(YTSendSMSServiceImpl.class);
private final static int pageSize = 100; //定义批量发送的条数
/**
* 上海移通消息中心,通知类型的短信发送接口
*
* 使用限制:1. 批量发送短信,只能是相同内容。
* 2. 只支持发送国内短信,不支持发送国际短信。
*
* 备注:1. 当前接口发送失败为统一失败,不存在同一批次的短信,部分失败,部分成功。
* 2. 配置的参数暂时先写死在程序中,由于需要紧急切换(缺点:不安全,如果后面发生信息改变,不易切换)。
*
* @param mobileList 批量发送手机号码
* @param content 发送短信的内容
* @param params 短信内容里面可以替换的参数
* @return 发送成功的列表,发送失败返回空
*
* @throws Exception HTTP发送请求异常
*
* @add 2018-07-30 添加移通发送短信的功能 by 邓新飞
* @Modify
*/
@Override
public Response<SendNoticeResultBean> sendSMS(List<String> mobileList, String content, Map<String, String> params) throws Exception {
logger.info("Begin send sms by YiTong. mobileList={}, content={}, params={}", mobileList, content, params);
//(1)定义返回的参数类型
SendNoticeResultBean bean = new SendNoticeResultBean();
List<String> successList = new ArrayList<String>();
//(2)判断发送的手机号码,如果发送的手机号码为空,直接返回
if(null == mobileList || mobileList.size() == 0) {
bean.setSendNum(0);
bean.setSuccessNum(0);
bean.setSuccessList(successList);
return new Response<SendNoticeResultBean>(bean);
}
//(3)分页处理短信发送情况
int size = mobileList.size();
if (size <= pageSize) {
successList.addAll(immediateSendSMS(mobileList, content, params));
} else {
int lastPageSize = size % pageSize;
int pageTotal = size / pageSize;
if (lastPageSize > 0) {
pageTotal += 1;
}
for (int i = 0; i < pageTotal; i++) {
int begin = i * pageSize;
int end = (i + 1) * pageSize < size ? (i + 1) * pageSize : size;
successList.addAll(immediateSendSMS(mobileList.subList(begin, end), content, params));
}
}
logger.info("sendSMS success with mobileList={}, content={}, params={}", mobileList.size(), content, params);
//(4)组装返回结果
bean.setSendNum(successList.size());
bean.setSuccessNum(successList.size());
bean.setSuccessList(successList);
return new Response<SendNoticeResultBean>(bean);
}
/**
* 直接发送短信-使用上海移通进行短信发送
*
* @param mobileList
* @param content
* @param params
* @return
* @throws Exception
*/
private List<String> immediateSendSMS(List<String> mobileList, String content, Map<String, String> params) throws Exception {
//(1)准备移通发送短信所需要的执行参数
String command = "MULTI_MT_REQUEST";// 操作命令、SP编号、SP密码,必填参数
String spid = "8020"; //参数spid为SP编号,必须填写
String sppassword = "yh8020@yoho"; //参数sppassword为SP帐号的密码,必须填写;
String spsc = "00"; // sp服务代码,可选参数,默认为 00
String url = "http://esms200.10690007.net/sms/mt"; //短信运营商发送请求的URL。
int dc = 15; // 下行内容以及编码格式,必填参数
//(2) 对发送短信内容进行重新编码
String sm = new String(Hex.encodeHex(content.getBytes("GBK")));
logger.debug("End recode send content. content={}, sm={}", content, sm);
//(4)整理发送短信的手机号码,按照移通支持的格式组装. 手机号码之间用,隔开
StringBuilder mobiles = new StringBuilder();
int size = mobileList.size();
for(int i = 0; i < size; i++){
if(mobileList.get(i).length() != 11 || !mobileList.get(i).startsWith("1") ){
logger.info("sms send mobile is invalid. mobile={}", mobileList.get(i));
continue;
}
if(i == (size - 1)){
mobiles.append("86" + mobileList.get(i));
continue;
}
mobiles.append("86" + mobileList.get(i) + ",");
}
//(3)组装发送请求的URL
StringBuilder smsUrl = new StringBuilder();
smsUrl.append(url);
smsUrl.append("?command=" + command);
smsUrl.append("&spid=" + spid);
smsUrl.append("&sppassword=" + sppassword);
smsUrl.append("&spsc=" + spsc);
smsUrl.append("&das=" + mobiles.toString());
smsUrl.append("&sm=" + sm);
smsUrl.append("&dc=" + dc);
//(3) 发送http请求,并接收http响应
Pair<Integer, String> result = HttpUtils.httpGet(smsUrl.toString(), null, "GBK", 1000);
if(result.getLeft() != 200){
return new ArrayList<String>();
}
return mobileList;
}
public static void main(String[] args) throws Exception {
String content = "您在Yoho!buy有货的预售订单5555商品已经到货,请及时付款。";
// String message = "校验码{code},南京技术部测试";
// String[] params = {"222222"};//1-9176028238
// //香港-852-98050283
// //美国 1-2066058408
// //日本 81-8041882889
// String result = YTSendSMSServiceImpl.sendMessage(content, "8618001582955,8618994021292", params);
// System.out.println("==================" + result + "====================");
YTSendSMSServiceImpl service = new YTSendSMSServiceImpl();
List<String> mobiles = new ArrayList<String>(5);
mobiles.add("18001582955");
mobiles.add("18994021292");
Response<SendNoticeResultBean> response = service.sendSMS(mobiles, content, null);
System.out.println("==============发送成功===================");
}
}
... ...
package com.yoho.yhmessage.sms.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PhoneUtil {
//中国国家码
private final static String CHINA_AREA = "86";
/**
* 判断号码是否是国内号码
*
* @param mobile
* @return
*/
public static boolean isDomestic(String mobile) {
if (null != mobile && !mobile.isEmpty()) {
mobile = ltrim(mobile, "0");
mobile = mobile.replaceAll("\\+", "");
String[] mobiles = mobile.split("-");
if (mobiles.length == 1) {
return true;
} else if (mobiles.length == 2
&& ("86".equals(mobiles[0].trim())
|| "086".equals(mobiles[0].trim()) || "0086"
.equals(mobiles[0].trim()))) {
return true;
}
}
return false;
}
/**
* 根据国家码判断是否是国内号码
*
* @param area 国家码
* @return boolean
*/
public static boolean isInternationalMobile(String area){
if(null == area || CHINA_AREA.equals(area)){
return true;
}
return false;
}
public static void main(String[] args) {
System.out.print(isMobile("15951889346@163.com"));
}
/**
* 手机号码加上国家码 : 如8612012221467
*
* @param mobile
* @return
*/
public static String makeMobile(String mobile){
//判断是否是国内号码,如果是国内号码, 则在号码前加上86, 如8612012221467
boolean isDomestic = PhoneUtil.isDomestic(mobile);
if(!isDomestic){ //如果不是国内号码
String[] mobiles = mobile.split("-");
if(null != mobiles && 2 == mobiles.length){
mobile = mobiles[0] + mobiles[1];
return mobile;
}
return mobile;
}
//如果不是国际号码,返回号码+86
return "86" + mobile;
}
public static boolean isMobile(String mobile){
if(null == mobile || "".equals(mobile)){
return false;
}
int mobileLength = mobile.length();
if(mobileLength>20){
return false;
}
//如果有字母也不是手机
String regex=".*[a-zA-Z]+.*";
Matcher m=Pattern.compile(regex).matcher(mobile);
if(m.matches()){
return false;
}
return true;
}
public static String ltrim(String message, String regex) {
if (message == null || message.isEmpty() || regex == null
|| regex.isEmpty()) {
return message;
}
while (message.indexOf(regex) == 0) {
message = message.substring(regex.length());
}
return message;
}
}
... ...
package com.yoho.yhmessage.sms.util;
public class StringUtil {
/**
* 函数移除字符串左侧的预定义字符。
*
* @param message 字符串内容
* @param regex 需要替换为空的字符串
* @return String
*/
public static String ltrim(String message, String regex) {
if (message == null || message.isEmpty() || regex == null
|| regex.isEmpty()) {
return message;
}
while (message.indexOf(regex) == 0) {
message = message.substring(regex.length());
}
return message;
}
/**
* 替換字符串{}中的內容
* @param message
* @param args
* @return
*/
public static String strFormat(String message, Object[] args){
if(StringUtil.isEmpty(message)){
return message;
}
int i = 0;
while(message.indexOf("{") != -1 && message.indexOf("}") != -1){
int startIndex = message.indexOf("{");
int endIndex = message.indexOf("}");
String startMsg = "";
String endMsg = "";
if(startIndex != 0){
startMsg = message;
startMsg = startMsg.substring(0, startIndex);
}
if(endIndex != message.length() - 1){
endMsg = message;
endMsg = endMsg.substring(endIndex + 1, message.length());
}
message = startMsg + args[i] + endMsg;
i++;
}
return message;
}
public static void main(String[] args) {
String message = "{sss}while loading:{dd}";
String[] param = {"xinfei", "test"};
System.out.println(StringUtil.strFormat(message, param));
}
/**
* 判断字符串是否为空
*
* @param str
* @return
*/
public static boolean isEmpty(String str) {
if (null == str || str.isEmpty()) {
return true;
}
return false;
}
}
... ...