抽取短信服务过程如下:
在父工程的interface 中创建ValidateCodeService接口, 创建sms_service_provider 编写接口的实现类,方便发送短信和校验验证码。
创建接口
在父工程的interface 中创建ValidateCodeService.java
public interface ValidateCodeService {
/**
* 发送验证码短信且存储到redis
* @param telephone 手机号码
* @param type 发送短信的类型:预约,登录,获取密码
* @param validateCode 要发送给用户的验证码
*/
public void sendValidateCodeShortMessage(String telephone, String type, String validateCode);
/**
* 校验验证码
* @param telephone 手机号码
* @param type 验证码的类型
* @param validateCode 用户输入的验证码
* @return
*/
public boolean checkValidateCode(String telephone , String type , String validateCode);
/**
* 发送通用短信
* @param telephone 手机号
* @param param 通用短信中的参数
*/
public void sendCommonShortMessage(String telephone, String... param);
}
创建短信服务模块
1.模块名称:sms_service_provider
2.导入依赖和插件
<!---依赖子工程-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>health_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 在父工程中指定版本 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<!-- 指定端口 -->
<port>88</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
1、编写日志文件
log.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE, info
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
2、编写spring-dubbo.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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 指定应用名称 -->
<dubbo:application name="sms_service_provider" />
<!--指定暴露服务的端口,如果不指定默认为20880-->
<dubbo:protocol name="dubbo" port="20881"/>
<!--指定服务注册中心地址-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!--批量扫描-->
<dubbo:annotation package="com.userbin" />
<!--
超时全局设置 10分钟
check=false 不检查服务提供方,开发阶段建议设置为false
check=true 启动时检查服务提供方,如果服务提供方没有启动则报错
-->
<dubbo:consumer timeout="6000" check="false"/>
</beans>
3、编写spring-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"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--Jedis连接池的相关配置-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal">
<value>200</value>
</property>
<property name="maxIdle">
<value>50</value>
</property>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
<constructor-arg name="host" value="127.0.0.1" />
<constructor-arg name="port" value="6379" type="int" />
<constructor-arg name="timeout" value="30000" type="int" />
</bean>
</beans>
4、编写web.xml
<!--读取dubbo和redis配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/*</param-value>
</context-param>
<!--添加监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
业务分析
import com.alibaba.dubbo.config.annotation.Service;
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;
import com.itheima.exception.BusinessRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@Service
@Slf4j
public class ValidateCodeServiceImpl implements ValidateCodeService {
private String accessKey = "";
private String secretKey = "";
private String signName = "";
private String validateCodeTemplateCode = "";
private String commonTemplateCode = "";
/**
* 发送验证码短信
* @param telephone 手机号码
* @param type 发送短信的类型: 预约,登录,获取密码
* @param validateCode 要发送给用户的验证码
*/
@Override
public void sendValidateCodeShortMessage(String telephone, String type, String validateCode) {
// 要想发送短信,必须配置认证信息(鉴权)(密钥)
// 需要调整的内容: 密钥,手机号码, 签名, 模板, 验证码
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKey, secretKey);
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com");
request.setSysVersion("2017-05-25");
request.setSysAction("SendSms");
request.putQueryParameter("RegionId", "cn-hangzhou");
request.putQueryParameter("PhoneNumbers", telephone);
request.putQueryParameter("SignName", signName);
request.putQueryParameter("TemplateCode", validateCodeTemplateCode);
request.putQueryParameter("TemplateParam", "{\"code\":\""+validateCode+"\"}");
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
if(response.getHttpStatus() == 200){
log.debug("发送验证码短信成功!!!");
//发送成功后,需要存储验证码到redis
saveValidateCodeToRedis(telephone,type,validateCode);
}else{
log.debug("发送验证码短信失败");
throw new BusinessRuntimeException("发送验证码失败!!!");
}
} catch (Exception e) {
e.printStackTrace();
log.debug("发送验证码短信失败");
throw new BusinessRuntimeException("发送验证码失败!!!");
}
}
@Autowired
JedisPool jedisPool;
/**
*
* 13400000000 : 123456
*
* 存储验证码到redis中
*
* 类型 + 手机号码:key
* 验证码为:value
*
* 存储时间:5分钟
* @param telephone
* @param type
* @param validateCode
*/
private void saveValidateCodeToRedis(String telephone, String type, String validateCode){
Jedis jedis = jedisPool.getResource();
/**
* key : 键: 类型 + 手机号
* seconds: 存储时间:单位秒
* value : 验证码
*/
jedis.setex(type + "-" + telephone, 5 * 60, validateCode);
}
/**
* 检验验证码
* @param telephone 手机号码
* @param type 验证码的类型(手机快速登录, 预约服务的功能, 找回密码)
* @param validateCode 用户输入的验证码
* @return
*/
@Override
public boolean checkValidateCode(String telephone, String type, String validateCode) {
//redis中取出验证码
Jedis jedis = jedisPool.getResource();
String validateCodeInRedis = jedis.get(type + "-" + telephone);
if(validateCodeInRedis != null && validateCodeInRedis.equalsIgnoreCase(validateCode)){
log.debug("校验验证码成功!!!");
return true;
}
log.debug("校验验证码失败!!!");
return false;
}
/**
* 发送通用短信
* @param telephone 手机号
* @param param 通用短信中的参数
*/
@Override
public void sendCommonShortMessage(String telephone, String... param) {
log.debug("【企业】发送通用短信!!!!");
}
}
测试类
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.RedisMessageConstant;
import com.itheima.service.ValidateCodeService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.swing.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-dubbo.xml","classpath:spring-redis.xml"})
public class TestSMS {
@Reference
ValidateCodeService validateCodeService;
@Test
public void testSMS(){
validateCodeService.sendValidateCodeShortMessage("182********", RedisMessageConstant.SENDTYPE_LOGIN, "1234");
}
// @Test
public void testCheck(){
System.out.println(validateCodeService.checkValidateCode("182********", RedisMessageConstant.SENDTYPE_LOGIN, "1234"));
}
}