first commit

This commit is contained in:
Ray
2026-02-19 03:37:37 +08:00
commit ccfd8c79a4
2813 changed files with 453657 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Sms253</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@@ -0,0 +1,3 @@
INSERT INTO `T_SYSPARA` VALUES ('smsbao_url', 'smsbao_url', null, '', '100', '2', '短信宝URL');
INSERT INTO `T_SYSPARA` VALUES ('smsbao_u', 'smsbao_u', null, '', '100', '2', '短信宝用户名');
INSERT INTO `T_SYSPARA` VALUES ('smsbao_p', 'smsbao_p', null, '', '100', '2', '短信宝密码');

View File

@@ -0,0 +1,17 @@
package smsbao;
/**
* 短信发送异步发送写入SmsMessageQueue队列返回
*
*/
public interface SmsSendService {
/**
* 单发短信
*
* @param mobile 手机号
* @param content 短信内容
*/
public void send(String mobile, String content);
}

View File

@@ -0,0 +1,4 @@
package smsbao.exception;
public class InvalidMobileException extends RuntimeException {
}

View File

@@ -0,0 +1,4 @@
package smsbao.exception;
public class InvalidSmsContentException extends RuntimeException {
}

View File

@@ -0,0 +1,176 @@
package smsbao.internal;
import java.net.Socket;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.params.SyncBasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.ImmutableHttpProcessor;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;
import org.apache.http.util.EntityUtils;
public class HttpClientUtil {
HttpParams params;
HttpProcessor httpproc;
HttpRequestExecutor httpexecutor;
HttpContext context;
HttpHost host;
DefaultHttpClientConnection conn;
ConnectionReuseStrategy connStrategy;
String sendURL = "";
public HttpClientUtil(String ip, int port, String SendURL) {
this.sendURL = SendURL;
params = new SyncBasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "GB2312");
HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
HttpProtocolParams.setUseExpectContinue(params, true);
httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
// Required protocol interceptors
new RequestContent(), new RequestTargetHost(),
// Recommended protocol interceptors
new RequestConnControl(), new RequestUserAgent(), new RequestExpectContinue() });
httpexecutor = new HttpRequestExecutor();
context = new BasicHttpContext(null);
host = new HttpHost(ip, port);
conn = new DefaultHttpClientConnection();
connStrategy = new DefaultConnectionReuseStrategy();
context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
}
public String sendGetMessage(String user, String pwd, String ServiceID, String dest, String sender, String msg) {
String msgid = "";
try {
if (!conn.isOpen()) {
Socket socket = new Socket(host.getHostName(), host.getPort());
conn.bind(socket, params);
}
String par = sendURL.trim() + "?src=%s&pwd=%s&ServiceID=%s&dest=%s&sender=%s&msg=%s";
String url = String.format(par, user, pwd, ServiceID, dest, sender, msg);
// String url = String.format(par, user, pwd, ServiceID, dest, sender,
// URLEncoder.encode(msg, "GB2312"));
BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("GET", url);
request.getRequestLine().getUri();
// System.out.println(">> Request URI: " + request.getRequestLine().getUri());
request.setParams(params);
httpexecutor.preProcess(request, httpproc, context);
HttpResponse response = httpexecutor.execute(request, conn, context);
response.setParams(params);
httpexecutor.postProcess(response, httpproc, context);
response.getStatusLine();
// DeBug("<< Response: " + response.getStatusLine());
msgid = EntityUtils.toString(response.getEntity());
// DeBug(msgid);
// DeBug("==============");
if (!connStrategy.keepAlive(response, context)) {
conn.close();
} else {
// System.out.println("Connection kept alive...");
conn.close();
}
} catch (Exception e) {
msgid = "";
} finally {
return msgid;
}
}
public String sendPostMessage(String user, String pwd, String ServiceID, String dest, String sender, String msg) {
String msgid = "";
try {
String parf = "src=%s&pwd=%s&ServiceID=%s&dest=%s&sender=%s&msg=%s";
String par = String.format(parf, user, pwd, ServiceID, dest, sender, msg);
// String url = String.format(par, user, pwd, ServiceID, dest, sender,
// URLEncoder.encode(msg, "GB2312"));
BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", sendURL.trim());
request.getRequestLine().getUri();
// System.out.println(">> Request URI: " + request.getRequestLine().getUri());
// System.out.println(">> Request URI:" + par);
byte[] data1 = par.getBytes("ASCII");
ByteArrayEntity entiy = new ByteArrayEntity(data1);
// hwRequest.ContentType = "application/x-www-form-urlencoded";
// hwRequest.ContentLength = bData.Length;
entiy.setContentType("application/x-www-form-urlencoded");
request.setEntity(entiy);
request.getRequestLine().getMethod();
// System.out.println(">> Request URI: " + request.getRequestLine().getMethod());
request.setParams(params);
if (!conn.isOpen()) {
Socket socket = new Socket(host.getHostName(), host.getPort());
conn.bind(socket, params);
}
HeaderIterator it = request.headerIterator();
while (it.hasNext()) {
Header hesd = it.nextHeader();
// System.out.println(">> Request Header: " + hesd.getName() + " : " + hesd.getValue());
}
httpexecutor.preProcess(request, httpproc, context);
HttpResponse response = httpexecutor.execute(request, conn, context);
response.setParams(params);
httpexecutor.postProcess(response, httpproc, context);
response.getStatusLine();
// DeBug("<< Response: " + response.getStatusLine());
msgid = EntityUtils.toString(response.getEntity());
// DeBug(msgid);
// DeBug("==============");
if (!connStrategy.keepAlive(response, context)) {
conn.close();
} else {
// System.out.println("Connection kept alive...");
conn.close();
}
conn.close();
} catch (Exception e) {
msgid = "";
} finally {
return msgid;
}
}
public static void DeBug(Object obj) {
System.out.println(obj);
}
}

View File

@@ -0,0 +1,13 @@
package smsbao.internal;
import smsbao.sender.SmsMessage;
public interface InternalSmsSenderService {
/**
* 短信发送
*
* @param smsMessage 短信内容
*/
public void send(SmsMessage smsMessage);
}

View File

@@ -0,0 +1,268 @@
package smsbao.internal;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import kernel.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import project.log.SysLogService;
import project.syspara.SysparaService;
import smsbao.exception.InvalidMobileException;
import smsbao.exception.InvalidSmsContentException;
import smsbao.sender.SmsMessage;
public class InternalSmsSenderServiceImpl implements InternalSmsSenderService {
private Logger log = LoggerFactory.getLogger(InternalSmsSenderServiceImpl.class);
private SysparaService sysparaService;
private SysLogService sysLogService;
private static final Pattern MobileFetchPattern = Pattern.compile("(\\d+)(\\s)*(\\d+)");
@Override
public void send(SmsMessage smsMessage) {
// 目的号码,注意:拼接的号码之间可能有空格,需要剔除
String dest = smsMessage.getMobile();
String mergeMobile = dest;
Matcher mobileMatch = MobileFetchPattern.matcher(dest);
if (mobileMatch.find()) {
mergeMobile = mobileMatch.group(1) + mobileMatch.group(3);
}
/**
* 发送的短信接口类型 tiantian---天天---smsSendService--->>>>--
* moduyun---摩杜云---smsSingleSender
*/
String send_code_type = this.sysparaService.find("send_code_type").getValue();
if ("tiantian".equals(send_code_type)) {
// 用户名
String user = sysparaService.find("smsbao_u").getValue();
// 密码:
String pwd = sysparaService.find("smsbao_p").getValue();
String ip = "";
String sendResult = "";
if (smsMessage.getInter()) {
ip = "210.51.190.232";
int port = 8085;
HttpClientUtil util = new HttpClientUtil(ip, port, "/mt/MT3.ashx");
String ServiceID = "SEND";
// 原号码
String sender = "";
// 短信内容
String msg = smsMessage.getContent();
// UTF-16BE
String hex = WebNetEncode.encodeHexStr(8, msg);
hex = hex.trim() + "&codec=8";
sendResult = util.sendPostMessage(user, pwd, ServiceID, mergeMobile, sender, hex);
log.info("tiantian--" + mergeMobile + ",短信内容:" + smsMessage.getContent() + "--验证码发送返回信息 = "
+ sendResult);
System.out.println("验证码发送返回信息 = " + sendResult);
} else {
ip = "210.51.190.233";
int port = 8085;
HttpClientUtil util = new HttpClientUtil(ip, port, "/mt/MT3.ashx");
String ServiceID = "SEND";
// 原号码
String sender = "";
// 短信内容
String msg = smsMessage.getContent();
// UTF-16BE
String hex = WebNetEncode.encodeHexStr(8, msg);
hex = hex.trim() + "&codec=8";
sendResult = util.sendPostMessage(user, pwd, ServiceID, mergeMobile, sender, hex);
log.info("tiantian--" + mergeMobile + ",短信内容:" + smsMessage.getContent() + "--验证码发送返回信息 = "
+ sendResult);
System.out.println("验证码发送返回信息 = " + sendResult);
}
// 错误码规范http://www.isms360.com/channel.aspx?id=25
if (StringUtils.isNullOrEmpty(sendResult)) {
return;
} else if (!sendResult.trim().startsWith("-")) {
// 不是错误码
return;
} else if (sendResult.trim().equals("-4")) {
// 目的号码运营商不在服务覆盖范围
throw new InvalidMobileException();
} else if (sendResult.trim().equals("-10")) {
// DEST参数格式错误
throw new InvalidMobileException();
} else if (sendResult.trim().equals("-15")) {
// 非法手机号码,手机号码格式不对
throw new InvalidMobileException();
} else if (sendResult.trim().equals("-18")) {
// 目的手机号码限制
throw new InvalidMobileException();
} else if (sendResult.trim().equals("-16")) {
// 短信内容超长UNICODE最大70个字符Alphabet编码英文即以此方式传输最大160字符
throw new InvalidSmsContentException();
} else if (sendResult.trim().equals("-17")) {
// 短信内容含有非法字符
throw new InvalidSmsContentException();
} else if (sendResult.trim().equals("-19")) {
// 短信内容编码不对比如发中文、韩文、日文而用Alphabet编码方式
throw new InvalidSmsContentException();
}
} else if ("smsbao".equals(send_code_type)) {
String username = sysparaService.find("smsbao_u").getValue(); // 在短信宝注册的用户名
String password = sysparaService.find("smsbao_p").getValue(); // 在短信宝注册的密码
String httpUrl = null;
if (smsMessage.getInter()) {
// 国际
httpUrl = "http://api.smsbao.com/wsms";
// 国际
// httpUrl = "http://iauhnbqszxl.site";
} else {
httpUrl = "http://api.smsbao.com/sms";
// httpUrl = "http://xahsdfg.site";
}
StringBuffer httpArg = new StringBuffer();
httpArg.append("u=").append(username).append("&");
httpArg.append("p=").append(md5(password)).append("&");
if (smsMessage.getInter()) {
// 国际
httpArg.append("m=").append(encodeUrlString("+", "UTF-8") + mergeMobile).append("&");
} else {
httpArg.append("m=").append(mergeMobile.substring(2, mergeMobile.length()))
.append("&");
}
httpArg.append("c=").append(encodeUrlString(smsMessage.getContent(), "UTF-8"));
String result = request(httpUrl, httpArg.toString());
if (!"0".equals(result)) {
log.info("Smsbao--" + mergeMobile + ",短信内容:" + smsMessage.getContent() + "--验证码发送失败 ");
} else {
log.info("Smsbao--" + mergeMobile + ",短信内容:" + smsMessage.getContent() + "--验证码发送成功 ");
}
}
}
public static void main(String[] args) {
String httpUrl = "http://api.smsbao.com/wsms";
// 区域编号+手机号66 939462175
String mobile = "662939462175";
String message = "手机号没空格,能收到短信吗";
String username = "duanxin19";
String password = "#ynwt|1u6Ngw";
// StringBuffer httpArg = new StringBuffer();
// httpArg.append("u=").append("duanxin19").append("&");
// httpArg.append("p=").append(md5("#ynwt|1u6Ngw")).append("&");
// httpArg.append("m=").append(encodeUrlString("+", "UTF-8") + mobile).append("&");
// httpArg.append("c=").append(encodeUrlString(message, "UTF-8"));
// String result = request(httpUrl, httpArg.toString());
// System.out.println("==========> result = " + result);
// String str = "test++test!"; // 746573742B2B7465737421
// str = "测试++"; // 6D4B8BD5002B002BFF01
// String hex = WebNetEncode.encodeHexStr(8, str);
// System.out.println("---> hex:" + hex); // 746573742B2B7465737421
String ip = "210.51.190.232";
int port = 8085;
HttpClientUtil util = new HttpClientUtil(ip, port, "/mt/MT3.ashx");
String ServiceID = "SEND";
// UTF-16BE
String hex = WebNetEncode.encodeHexStr(8, message);
hex = hex.trim() + "&codec=8";
String sendResult = util.sendPostMessage(username, password, ServiceID, mobile, "", hex);
System.out.println("验证码发送返回信息 = " + sendResult);
}
public static String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
System.out.println("=====> 短信发送完整请求地址:" + httpUrl);
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = reader.readLine();
if (strRead != null) {
sbf.append(strRead);
while ((strRead = reader.readLine()) != null) {
sbf.append("\n");
sbf.append(strRead);
}
}
reader.close();
result = sbf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String md5(String plainText) {
StringBuffer buf = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return buf.toString();
}
public static String encodeUrlString(String str, String charset) {
String strret = null;
if (str == null)
return str;
try {
strret = java.net.URLEncoder.encode(str, charset);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return strret;
}
public void setSysparaService(SysparaService sysparaService) {
this.sysparaService = sysparaService;
}
public void setSysLogService(SysLogService sysLogService) {
this.sysLogService = sysLogService;
}
}

View File

@@ -0,0 +1,27 @@
package smsbao.internal;
import cn.hutool.core.util.StrUtil;
import smsbao.SmsSendService;
import smsbao.sender.SmsMessage;
import smsbao.sender.SmsMessageQueue;
public class SmsSendServiceImpl implements SmsSendService {
@Override
public void send(String mobile, String content) {
if (StrUtil.isBlank(mobile) || mobile.trim().length() < 3) {
System.out.println("---> SmsSendServiceImpl.send 传入的手机号信息不合规:" + mobile);;
throw new RuntimeException("手机号信息不正确:" + mobile);
}
SmsMessage smsMessage = new SmsMessage(mobile, content);
String strh = "";
strh = mobile.substring(0, 2);
if ("86".equals(strh)) {
smsMessage.setInter(false);
}
SmsMessageQueue.add(smsMessage);
}
}

View File

@@ -0,0 +1,112 @@
package smsbao.internal;
/**
*
* @author Administrator
*/
public class WebNetEncode {
//字符编码成HEX
public static String toHexString(String s) {
String str = "";
for (int i = 0; i < s.length(); i++) {
int ch = (int) s.charAt(i);
String s4 = Integer.toHexString(ch);
str = str + s4;
}
return "0x" + str;//0x表示十六进制
}
//转换十六进制编码为字符串
public static String toStringHex(String s) {
if ("0x".equals(s.substring(0, 2))) {
s = s.substring(2);
}
byte[] baKeyword = new byte[s.length() / 2];
for (int i = 0; i < baKeyword.length; i++) {
try {
baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
s = new String(baKeyword, "GBK");//UTF-16le:Not
} catch (Exception e1) {
e1.printStackTrace();
}
return s;
}
/** *//**
* 把字节数组转换成16进制字符串
* @param bArray
* @return
*/
public static final String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
//字符编码成HEX
public static String encodeHexStr(int dataCoding, String realStr) {
String strhex = "";
try {
byte[] bytSource = null;
if (dataCoding == 15) {
bytSource = realStr.getBytes("GBK");
} else if (dataCoding == 3) {
bytSource = realStr.getBytes("ISO-8859-1");
} else if (dataCoding == 8) {
bytSource = realStr.getBytes("UTF-16BE");
} else {
bytSource = realStr.getBytes("ASCII");
}
strhex = bytesToHexString(bytSource);
} catch (Exception e) {
e.printStackTrace();
}
return strhex;
}
//hex编码还原成字符
public static String decodeHexStr(int dataCoding, String hexStr) {
String strReturn = "";
try {
int len = hexStr.length() / 2;
byte[] bytSrc = new byte[len];
for (int i = 0; i < len; i++) {
String s = hexStr.substring(i * 2, 2);
bytSrc[i] = Byte.parseByte(s, 512);
Byte.parseByte(s, i);
//bytSrc[i] = Byte.valueOf(s);
//bytSrc[i] = Byte.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier);
}
if (dataCoding == 15) {
strReturn = new String(bytSrc, "GBK");
} else if (dataCoding == 3) {
strReturn = new String(bytSrc, "ISO-8859-1");
} else if (dataCoding == 8) {
strReturn = new String(bytSrc, "UTF-16BE");
//strReturn = Encoding.BigEndianUnicode.GetString(bytSrc);
} else {
strReturn = new String(bytSrc, "ASCII");
//strReturn = System.Text.ASCIIEncoding.ASCII.GetString(bytSrc);
}
} catch (Exception e) {
e.printStackTrace();
}
return strReturn;
}
}

View File

@@ -0,0 +1,12 @@
package smsbao.sender;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class OffLineEventRejectExecutingHandler implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
}
}

View File

@@ -0,0 +1,64 @@
package smsbao.sender;
/**
*
* <p>
* Description: 短信消息类
* </p>
*/
public class SmsMessage {
/**
* 要发送的电话号码
*/
private String mobile;
/**
* 要发送的短信内容
*/
private String content;
// 是否是国外(中国大陆外)手机号
private boolean inter = true;
/**
* 无参构造函数
*/
public SmsMessage() {
}
/**
* 构造函数
*
* @param phones 电话号码
* @param content 短信内容
*/
public SmsMessage(String mobile, String content) {
this.mobile = mobile;
this.content = content;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public boolean getInter() {
return inter;
}
public void setInter(boolean inter) {
this.inter = inter;
}
}

View File

@@ -0,0 +1,35 @@
package smsbao.sender;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SmsMessageQueue {
private static final Log logger = LogFactory.getLog(SmsMessageQueue.class);
private static ConcurrentLinkedQueue<SmsMessage> WORKING_EVENTS = new ConcurrentLinkedQueue<SmsMessage>();
public static void add(SmsMessage item) {
try {
WORKING_EVENTS.add(item);
} catch (Throwable e) {
logger.error("add(SmsMessage item) fail : ", e);
}
}
public static int size() {
return WORKING_EVENTS.size();
}
public static SmsMessage poll() {
SmsMessage item = null;
try {
item = WORKING_EVENTS.poll();
} catch (Throwable e) {
logger.error("SmsMessage poll() fail : ", e);
}
return item;
}
}

View File

@@ -0,0 +1,106 @@
package smsbao.sender;
import email.sender.EmailServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.task.TaskExecutor;
import kernel.util.ThreadUtils;
import smsbao.exception.InvalidMobileException;
import smsbao.internal.InternalSmsSenderService;
import java.util.HashMap;
import java.util.Map;
/**
* 短信服务类,负责从短信消息队列取出短信消息并发送
*/
public class SmsServer implements InitializingBean, Runnable {
//private static Log logger = LogFactory.getLog(SmsServer.class);
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SmsServer.class);
private TaskExecutor taskExecutor;
private InternalSmsSenderService internalSmsSenderService;
// 优化
// 一次发送失败的手机号,在 5 分钟内再次遇到发送同一手机号的短信时直接忽略
long invalidTimeout = 5L * 60L * 1000L;
// 记录发送失败的手机号上次真实发送的时间戳
private Map<String, Long> failMobileMap = new HashMap();
/**
* 服务运行: 1. 从消息队列获取message 2.调用currentProvider发送短信
*/
public void run() {
while (true) {
try {
SmsMessage item = SmsMessageQueue.poll();
if (item != null) {
long now = System.currentTimeMillis();
Long lastSendTime = failMobileMap.get(item.getMobile());
if (lastSendTime != null && lastSendTime > 0) {
if (lastSendTime + invalidTimeout > now) {
// 上次发送失败,并且还没过时限,忽略本次发送
logger.warn("当前待发送消息的目标手机:" + item.getMobile() + " 在时刻:" + lastSendTime + " 发送失败,尚未过冷却期,忽略本次消息的发送, 消息内容:" + item.getContent());
continue;
}
}
taskExecutor.execute(new HandleRunner(item));
} else {
/*
* 限速最多1秒2个
*/
ThreadUtils.sleep(500);
}
} catch (Throwable e) {
logger.error("SmsServer taskExecutor.execute() fail", e);
}
}
}
public class HandleRunner implements Runnable {
private SmsMessage item;
public HandleRunner(SmsMessage item) {
this.item = item;
}
public void run() {
long now = System.currentTimeMillis();
try {
internalSmsSenderService.send(item);
} catch (InvalidMobileException e) {
failMobileMap.put(this.item.getMobile(), now);
logger.error("SmsServer taskExecutor.execute() fail, mobile:" + item.getMobile(), e);
} catch (Throwable t) {
logger.error("SmsServer taskExecutor.execute() fail", t);
}
}
}
public void afterPropertiesSet() throws Exception {
new Thread(this, "SmsbaoServer").start();
if (logger.isInfoEnabled()) {
logger.info("启动短信(Smsbao)服务!");
}
}
public void setTaskExecutor(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void setInternalSmsSenderService(InternalSmsSenderService internalSmsSenderService) {
this.internalSmsSenderService = internalSmsSenderService;
}
}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<bean id="smsSendService"
class="smsbao.internal.SmsSendServiceImpl">
</bean>
<bean id="internalSmsSenderService"
class="smsbao.internal.InternalSmsSenderServiceImpl">
<property name="sysparaService" ref="sysparaService" />
<property name="sysLogService" ref="sysLogService" />
</bean>
<bean id="smsbaoServer" class="smsbao.sender.SmsServer">
<property name="taskExecutor" ref="smsbaoSendThreadPool" />
<property name="internalSmsSenderService" ref="internalSmsSenderService" />
</bean>
<bean id="smsbaoSendThreadPool"
class="kernel.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1" />
<property name="keepAliveSeconds" value="60" />
<property name="maxPoolSize" value="2" />
<property name="queueCapacity" value="100" />
<property name="rejectedExecutionHandler"
ref="smsbaoSendThreadRejectExecutingHandler" />
</bean>
<bean id="smsbaoSendThreadRejectExecutingHandler"
class="kernel.util.RejectExecutionHandlerDelegator">
<property name="rejectExecutionHandlers">
<list>
<bean class="smsbao.sender.OffLineEventRejectExecutingHandler" />
</list>
</property>
</bean>
</beans>