1.工程目录如下
2.接入消息中间件activeMQ
加入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.13.4</version>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<version>2.0.1</version>
</dependency>
这里的消息需要点对点模式,加入提供者配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.2.2:61616"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!--这个是队列目的地,点对点的 文本信息-->
<bean id="smsDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="sms"/>
</bean>
</beans>
加入消费者配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.2.2:61616"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- 点对点模式,接收sms消息-->
<bean id="queueSMSDestination" class="org.apache.activemq.command.ActiveMQQueue">
<!--指定从这个队列中去接收SMS信息-->
<constructor-arg value="sms"/>
</bean>
<!-- 点对点模式, 消息监听容器 发送短信-->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueSMSDestination" />
<property name="messageListener" ref="smsListener" />
</bean>
<bean id="smsListener" class="com.dongpo.core.listener.SMSListener"></bean>
</beans>
3.接入redis
这里主要用来缓存验证码,手机号作为key,用户注册时输入的验证码与redis缓存作比较。
加入pom依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
redis的properties配置文件如下,此时没有设置密码
redis.host=192.168.2.2
redis.port=6379
redis.pass=
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
redis的xml配置如下
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath*:/properties/*.properties" />
<!-- redis 相关配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<bean id="JedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}"
p:port="${redis.port}"
p:password="${redis.pass}"
p:pool-config-ref="poolConfig"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="JedisConnectionFactory" />
</bean>
</beans>
4.接入alibaba短信服务
加入pom依赖
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
基本业务流程:controller调用service传递phone参数,service进行生成验证码,存储到redis中,并且将手机号,短信内容,签名,模板封装成map发送到消息队列中。消息监听器监听到会调用smsUtil发送短信。
service层代码如下
package com.dongpo.core.service.impl;
import com.alibaba.fastjson.JSON;
import com.dongpo.core.service.UserService;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* @className UserServiceImpl
* @Description: TODO
* @Author dongpo
* @Date 2020/3/25
* @Version V1.0
**/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private ActiveMQQueue smsDestination;
public void sendCode(final String phone){
//1. 生成一个随机6为数字, 作为验证码
StringBuffer sb = new StringBuffer();
for (int i =1; i < 7; i++) {
int s = new Random().nextInt(10);
sb.append(s);
}
//2. 手机号作为key, 验证码作为value保存到redis中, 生存时间为10分钟
redisTemplate.boundValueOps(phone).set(sb.toString(), 60 * 10, TimeUnit.SECONDS);
final String smsCode = sb.toString();
//3. 将手机号, 短信内容, 模板编号, 签名封装成map消息发送给消息服务器
jmsTemplate.send(smsDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
MapMessage message = session.createMapMessage();
message.setString("mobile", phone);//手机号
message.setString("template_code", "***");//模板编码
message.setString("sign_name", "**");//签名
Map map=new HashMap();
map.put("code", ***); //验证码
message.setString("param", JSON.toJSONString(map));
return (Message) message;
}
});
}
}
listener监听器代码如下
package com.dongpo.core.listener;
import com.dongpo.core.util.SmsUtil;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
public class SMSListener implements MessageListener {
@Override
public void onMessage(Message message) {
MapMessage map = (MapMessage)message;
try {
SmsUtil.sendSms( map.getString("mobile"),
map.getString("template_code"),
map.getString("sign_name"),
map.getString("param"));
} catch (JMSException e) {
e.printStackTrace();
}
}
}
smsUtil代码如下
package com.dongpo.core.util;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
public class SmsUtil {
/**
* 发送短信
* @param mobile 手机号
* @param template_code 模板号
* @param sign_name 签名
* @param param 验证码
*/
public static void sendSms(String mobile,String template_code,String sign_name,String param) {
DefaultProfile profile = DefaultProfile.getProfile("**", "**", "**");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("**");
request.setVersion("**");
request.setAction("**");
request.putQueryParameter("**", "**");
request.putQueryParameter("**", mobile);
request.putQueryParameter("**", sign_name);
request.putQueryParameter("***", template_code);
request.putQueryParameter("TemplateParam",param);
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (Exception e) {
e.printStackTrace();
}
}
}