重构客户注册-基于ActiveMQ实现短信验证码生产者
重构目标:将bos_fore项目中的CustomerAction作为短信消息生产者,将消息发给ActiveMQ,创建一个单独的SMS项目,作为短信息的消费者,从ActiveMQ获取短信消息,调用第三方接口完成短信发送。
CustomerAction完整代码:
1 @ParentPackage("json-default") 2 @Namespace("/") 3 @Controller 4 @Scope("prototype") 5 public class CustomerAction extends BaseAction<Customer> { 6 @Autowired 7 @Qualifier("jmsQueueTemplate") 8 private JmsTemplate jmsTemplate; 9 10 @Action(value = "customer_sendSms") 11 public String sendSms() throws IOException { 12 // 手机号保存在Customer对象 13 // 生成短信验证码 14 String randomCode = RandomStringUtils.randomNumeric(4); 15 // 将短信验证码 保存到session 16 ServletActionContext.getRequest().getSession() 17 .setAttribute(model.getTelephone(), randomCode); 18 19 System.out.println("生成手机验证码为:" + randomCode); 20 // 编辑短信内容 21 final String msg = "尊敬的用户您好,本次获取的验证码为:" + randomCode 22 + ",服务电话:4007654321"; 23 24 // 调用MQ服务,发送一条消息 25 jmsTemplate.send("bos_sms", new MessageCreator() { 26 @Override 27 public Message createMessage(Session session) throws JMSException { 28 MapMessage mapMessage = session.createMapMessage(); 29 mapMessage.setString("telephone", model.getTelephone()); 30 mapMessage.setString("msg", msg); 31 return mapMessage; 32 } 33 }); 34 return NONE; 35 36 } 37 38 // 属性驱动 39 private String checkcode; 40 41 public void setCheckcode(String checkcode) { 42 this.checkcode = checkcode; 43 } 44 45 @Autowired 46 private RedisTemplate<String, String> redisTemplate; 47 48 @Action(value = "customer_regist", results = { 49 @Result(name = "success", type = "redirect", location = "signup-success.html"), 50 @Result(name = "input", type = "redirect", location = "signup.html") }) 51 public String regist() { 52 // 先校验短信验证码,如果不通过,调回注册页面 53 // 从session获取 之前生成验证码 54 String checkcodeSession = (String) ServletActionContext.getRequest() 55 .getSession().getAttribute(model.getTelephone()); 56 if (checkcodeSession == null || !checkcodeSession.equals(checkcode)) { 57 System.out.println("短信验证码错误..."); 58 // 短信验证码错误 59 return INPUT; 60 } 61 // 调用webService 连接CRM 保存客户信息 62 WebClient 63 .create("http://localhost:9002/crm_management/services" 64 + "/customerService/customer") 65 .type(MediaType.APPLICATION_JSON).post(model); 66 System.out.println("客户注册成功..."); 67 68 // 发送一封激活邮件 69 // 生成激活码 70 String activecode = RandomStringUtils.randomNumeric(32); 71 72 // 将激活码保存到redis,设置24小时失效 73 redisTemplate.opsForValue().set(model.getTelephone(), activecode, 24, 74 TimeUnit.HOURS); 75 76 // 调用MailUtils发送激活邮件 77 String content = "尊敬的客户您好,请于24小时内,进行邮箱账户的绑定,点击下面地址完成绑定:<br/><a href='" 78 + MailUtils.activeUrl + "?telephone=" + model.getTelephone() 79 + "&activecode=" + activecode + "'>速运快递邮箱绑定地址</a>"; 80 MailUtils.sendMail("速运快递激活邮件", content, model.getEmail()); 81 82 return SUCCESS; 83 } 84 85 // 属性驱动 86 private String activecode; 87 88 public void setActivecode(String activecode) { 89 this.activecode = activecode; 90 } 91 92 @Action("customer_activeMail") 93 public String activeMail() throws IOException { 94 ServletActionContext.getResponse().setContentType( 95 "text/html;charset=utf-8"); 96 // 判断激活码是否有效 97 String activecodeRedis = redisTemplate.opsForValue().get( 98 model.getTelephone()); 99 if (activecodeRedis == null || !activecodeRedis.equals(activecodeRedis)) { 100 // 激活码无效 101 ServletActionContext.getResponse().getWriter() 102 .println("激活码无效,请登录系统,重新绑定邮箱!"); 103 } else { 104 // 激活码有效 105 // 防止重复绑定 106 // 调用CRM webService 查询客户信息,判断是否已经绑定 107 Customer customer = WebClient 108 .create("http://localhost:9002/crm_management/services" 109 + "/customerService/customer/telephone/" 110 + model.getTelephone()) 111 .accept(MediaType.APPLICATION_JSON).get(Customer.class); 112 if (customer.getType() == null || customer.getType() != 1) { 113 // 没有绑定,进行绑定 114 WebClient.create( 115 "http://localhost:9002/crm_management/services" 116 + "/customerService/customer/updatetype/" 117 + model.getTelephone()).get(); 118 ServletActionContext.getResponse().getWriter() 119 .println("邮箱绑定成功!"); 120 } else { 121 // 已经绑定过 122 ServletActionContext.getResponse().getWriter() 123 .println("邮箱已经绑定过,无需重复绑定!"); 124 } 125 126 // 删除redis的激活码 127 redisTemplate.delete(model.getTelephone()); 128 } 129 return NONE; 130 } 131 132 }
spring的配置文件applicationContext-mq.xml完整代码:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task" 7 xmlns:amq="http://activemq.apache.org/schema/core" 8 xmlns:jms="http://www.springframework.org/schema/jms" 9 xsi:schemaLocation=" 10 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 11 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd 12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd 13 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd 14 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd 15 http://www.springframework.org/schema/data/jpa 16 http://www.springframework.org/schema/data/jpa/spring-jpa.xsd 17 http://www.springframework.org/schema/jms 18 http://www.springframework.org/schema/jms/spring-jms.xsd 19 http://activemq.apache.org/schema/core 20 http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd "> 21 22 <!-- ActiveMQ 连接工厂 --> 23 <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供--> 24 <!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码--> 25 <amq:connectionFactory id="amqConnectionFactory" 26 brokerURL="tcp://localhost:61616" userName="admin" password="admin" /> 27 28 <!-- Spring Caching连接工厂 --> 29 <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> 30 <bean id="mqConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> 31 <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> 32 <property name="targetConnectionFactory" ref="amqConnectionFactory"></property> 33 <!-- 同上,同理 --> 34 <!-- <constructor-arg ref="amqConnectionFactory" /> --> 35 <!-- Session缓存数量 --> 36 <property name="sessionCacheSize" value="100" /> 37 </bean> 38 39 <!-- Spring JmsTemplate 的消息生产者 start--> 40 41 <!-- 定义JmsTemplate的Queue类型 --> 42 <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate"> 43 <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 44 <constructor-arg ref="mqConnectionFactory" /> 45 <!-- 非pub/sub模型(发布/订阅),即队列模式 --> 46 <property name="pubSubDomain" value="false" /> 47 </bean> 48 49 <!-- 定义JmsTemplate的Topic类型 --> 50 <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate"> 51 <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 --> 52 <constructor-arg ref="mqConnectionFactory" /> 53 <!-- pub/sub模型(发布/订阅) --> 54 <property name="pubSubDomain" value="true" /> 55 </bean> 56 57 <!--Spring JmsTemplate 的消息生产者 end--> 58 </beans>
maven的pom文件完整代码:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 2 <modelVersion>4.0.0</modelVersion> 3 4 <parent> 5 <groupId>cn.niwotaxuexiba.maven</groupId> 6 <artifactId>common_parent</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 </parent> 9 10 <artifactId>bos_fore</artifactId> 11 <packaging>war</packaging> 12 <name>bos_fore</name> 13 <description>物流前端系统</description> 14 15 <build> 16 <plugins> 17 <plugin> 18 <groupId>org.codehaus.mojo</groupId> 19 <artifactId>tomcat-maven-plugin</artifactId> 20 <version>1.1</version> 21 <configuration> 22 <port>9003</port> 23 </configuration> 24 </plugin> 25 <plugin> 26 <groupId>org.apache.maven.plugins</groupId> 27 <artifactId>maven-compiler-plugin</artifactId> 28 <version>2.3.2</version> 29 <configuration> 30 <source>1.8</source> 31 <target>1.8</target> 32 </configuration> 33 </plugin> 34 </plugins> 35 </build> 36 <dependencies> 37 <dependency> 38 <groupId>cn.niwotaxuexiba.maven</groupId> 39 <artifactId>crm_domain</artifactId> 40 <version>0.0.1-SNAPSHOT</version> 41 </dependency> 42 </dependencies> 43 </project>