天天看点

spring 异步发送短信

ThreadPoolTaskExecutor是一个spring的线程池技术,利用他可以轻松的视线线程池。

1.pom.xml

<dependency> 
<groupId>org.springframework</groupId> 
<artifactId>spring-context-support</artifactId> 
<version>3.0.5.RELEASE</version> 
</dependency> 
           

2. spring .xml

<bean id="threadPoolTaskExecutor"  
		class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">  
		 <!-- 线程池维护线程的最少数量 -->
		<property name="corePoolSize" value="50" />  
		 <!-- 线程池维护线程的最大数量 -->
		<property name="maxPoolSize" value="150" />  
		 <!-- 缓存队列 -->
		<property name="queueCapacity" value="1000" />  
	</bean>  
           

3. 短信发送实现接口 MessageResource.java

@Path("/message")
public class MessageResource{
	
	/** 验证码有效期 **/
	private static final long CAPTCHA_EXPIRED_TIME = 60 * 5;
	
	/** 短信发送服务 **/
	@Autowired
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;
	
	/** 对象转换器 **/
	@Autowired
	private HdUserBaseInfoService hdUserBaseInfoService;
	
	
	/**
	 * 发送短信验证码
	 */
	@GET
	@Path("/send/{mobile}/{type}")
	@Produces(RestContents.MEDIA_TYPE_APPLICATION_JSON_UTF8)
	public Object sendSms(@PathParam("mobile")String mobile, 
			@PathParam("type")int type,			
			@CookieParam(HD_LOGIN_USER_COOKIE_KEY) String sessionid,
			@QueryParam("jsonpCallback")String jsonpCallback,
    		@HeaderParam("User-Agent")String userAgent){
		RestObject<BaseRo> rest = new RestObject<BaseRo>();
		try{
			rest.setCode(ResultCode.VALID_NO_PASS.getCode());
			boolean flag = true;
			//手机号码验证
			if(flag && !HdCommonValidateUtil.isMobileLegal(mobile)){
				flag = false;
				rest.setMsg("短信验证码发送失败,原因:手机号码有误!");
			}
			//发送类型
			String smsSendType = HdCommonContext.UserMessageSendContext.getName(type);
			if(flag && (null == smsSendType)){
				flag = false;
				rest.setMsg("短信验证码发送失败,原因:发送类型有误!");
			}
			//在redis中做验证码验证
			if(flag){
				String redisKey = configUtil.getConfigByKey(HdUserCommonConstant.HD_USER_SMS_CAPTCHA)+HD_SEPARATE_COMMA+mobile+HD_SEPARATE_COMMA+type;
				Long expireTime = ttcRedis.ttl(redisKey);
				if(null != expireTime && (expireTime > 0l)){
					long overplus = CAPTCHA_EXPIRED_TIME - expireTime;
					if(overplus < 60l){
						flag = false;
						rest.setMsg("请过"+(60-overplus)+"秒之后再尝试!");
					}
				}
			}
			
			//验证手机号是否存在
			if(flag && (type == HdCommonContext.UserMessageSendContext.REGISTER.getCode()
					|| type == HdCommonContext.UserMessageSendContext.BOXER.getCode())){
				Long count = hdUserBaseInfoService.queryUserBaseInfoCountByMobile(mobile);
				if(count > 0l){
					flag = false;
					rest.setMsg("短信验证码发送失败,原因:该手机号已注册汇道体育,请登录!");
				}
			}

			//发送短信验证码
			if(flag){
				//生成短信验证码
				String captcha = CaptchaUtil.generateCaptcha();
				//写入redis
				String redisKey = configUtil.getConfigByKey(HdUserCommonConstant.HD_USER_SMS_CAPTCHA)+HD_SEPARATE_COMMA+mobile+HD_SEPARATE_COMMA+type;
				ttcRedis.set(redisKey, captcha, CAPTCHA_EXPIRED_TIME);
				//发送短信 
				sendMessage(mobile, captcha, type , CAPTCHA_EXPIRED_TIME/60);
				rest.setCode(ResultCode.SUCCESS.getCode());
				rest.setMsg("短信验证码发送成功,请查收!");
			}
			
		}catch(Exception ex){
			this.logger.error("短信验证码发送失败!" + mobile , ex);
			rest.setCode(ResultCode.ERROR.getCode());
			rest.setMsg("短信验证码发送失败,请稍后再试,原因:服务器出错!");
		}
		Object responseObject =  getResponseObject(jsonpCallback, rest);		
		return responseObject;
	}

	/**
	 * 
	   * 发送短信
	   * @param mobile
	   * @param code
	   * @param type
	 */
	private void sendMessage(String mobile , String code , int type , long time){
		//渠道
		String channel = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER__SMS_CLASS_NAME);
		HdUserSmsService channelSmsService = (HdUserSmsService)SpringContextUtil.getBean("hdUser"+channel+"SmsService");
		threadPoolTaskExecutor.execute(new HdUserSmsSendTask(channelSmsService, mobile , code , type , time));
	}
	
	
           

4.短信模板对象

public class HdUserSmsSendTask implements Runnable{
	
	/** 短信发送服务 **/
	private HdUserSmsService hdUserSmsService;
	
	/** 手机号码 **/
	private String mobile;
	
	/** 验证码 **/
	private String code;
	
	/** 发送类型 **/
	private int type;
	
	/** 超时时间 **/
	private  long time;	
	
	 /**
	  *@param hdUserSmsService
	  *@param mobile
	  *@param code
	  *@param type
	  *@param time
	  */
	public HdUserSmsSendTask(HdUserSmsService hdUserSmsService, String mobile,
			String code, int type, long time) {
		super();
		this.hdUserSmsService = hdUserSmsService;
		this.mobile = mobile;
		this.code = code;
		this.type = type;
		this.time = time;
	}

	/**
	 * 任务执行
	 * @see java.lang.Runnable#run()
	 */
	public void run(){
		hdUserSmsService.sendMessage(mobile , code, type, time);
	}
           

5.短信发送方法和实现类

public interface HdUserSmsService extends HdCommonSmsService{
	
	/**
	 * 
	 * 发送短信
	 * @param smsBean
	 */
	public void sendMessage(String mobile,String code, int type, long time);

}
           
@Service("hdUserQcloudSmsService")
public class HdUserQcloudSmsServiceImpl extends HdCommonSmsServiceImpl implements HdUserSmsService {

	/** 日志 **/
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	/** 配置文件服务 **/
	@Resource
	private ConfigUtil configUtil;
	
	/**
	 * 
	   * 发送短信
	   * @param smsBean
	 */
	public void sendMessage(String mobile,String code, int type, long time){
		
		HdCommonSmsBean smsBean = new HdCommonSmsBean();
		HdCommonSmsTelBean telBean = new HdCommonSmsTelBean();
		telBean.setMobile(mobile);
		smsBean.setTel(telBean);
		
		String[] params = new String[]{code , String.valueOf(time)};
		smsBean.setParams(params);
		
		if(HdCommonContext.UserMessageSendContext.LOGIN.getCode() == type){
			String templateId = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_LOGIN_TEMPLATE_ID);
			smsBean.setTpl_id(Integer.parseInt(templateId));
		}else if(HdCommonContext.UserMessageSendContext.REGISTER.getCode() == type){
			String templateId = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_REGISTER_TEMPLATE_ID);
			smsBean.setTpl_id(Integer.parseInt(templateId));
		}else if(HdCommonContext.UserMessageSendContext.BOXER.getCode() == type){
			String templateId = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_BOXER_TEMPLATE_ID);
			smsBean.setTpl_id(Integer.parseInt(templateId));
		}else if(HdCommonContext.UserMessageSendContext.CARD.getCode() == type){
			String templateId = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_BOXER_TEMPLATE_ID);
			smsBean.setTpl_id(Integer.parseInt(templateId));
		}
		
		String url = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_URL);
		String nationcode = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_NATIONCODE);
		smsBean.getTel().setNationcode(nationcode);
		String sdkappid = configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_SDKAPPID);
		url = url.replaceAll("#sdkappid#", sdkappid);
		String random = String.valueOf(System.currentTimeMillis());
		url = url.replaceAll("#random#", random);
		long times = System.currentTimeMillis()/1000;
		smsBean.setTime(times);
		String appkey= configUtil.getConfigByKey(HdCommonSmsConstants.HD_USER_SMS_APP_KEY);
		String sig = HdCommonEncryptUtil.SHA256("appkey="+appkey+"&random="+random+"&time="+times+"&mobile="+smsBean.getTel().getMobile());
		smsBean.setSig(sig);
		
		String jsonData =JSON.toJSONString(smsBean);
		String result = HdCommonHttpUtil.httpPost(url, jsonData);
		
		logger.info("短信回执:"+result);
	}
           

6.邮件参数常量

public class RainbowDataEmailConstant {
	
	/** 邮件发送主机 **/
	public static final String RAINBOW_MAIL_COMMON_HOST = "com.zjtachao.rainbow.mail.common.host";
	
	/** 邮件发送端口 **/
	public static final String RAINBOW_MAIL_COMMON_PORT = "com.zjtachao.rainbow.mail.common.port";
	
	/** 邮件发送来源地址 **/
	public static final String RAINBOW_MAIL_COMMON_FROM_ADDRESS = "com.zjtachao.rainbow.mail.common.from.address";
	
	/** 邮件发送名称 **/
	public static final String RAINBOW_MAIL_COMMON_FROM_NAME = "com.zjtachao.rainbow.mail.common.from.name";
	
	/** 邮件发送密码 **/
	public static final String RAINBOW_MAIL_COMMON_FROM_PWD = "com.zjtachao.rainbow.mail.common.from.pwd";
	

}
           

7.mail.properties

com.zjtachao.rainbow.mail.common.host=smtp.qq.com
com.zjtachao.rainbow.mail.common.port=465
[email protected]
com.zjtachao.rainbow.mail.common.from.name=xxxx
com.zjtachao.rainbow.mail.common.from.pwd=xxxx