申请短信服务 我使用的是阿里云的短信服务,然后就可以获得这两个值:
文章图片
引入依赖 这个依赖包含一个短信服务客户端Client:
com.aliyun
dysmsapi20170525
2.0.1
将客户端Client整合到SpringBoot中【灵魂】 方式一:原生SpringBoot配置过程(推荐方式二) 客户端自动配置类
/**
* @Author: xiang
* @Date: 2021/4/29 16:58
*
* 短信访问客户端
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SmsProperties.class) //指对应的明属性配置类
@AutoConfigureAfter(RedisAutoConfiguration.class) //短信功能依赖redis
public class SmsAutoConfiguration {//短信客户端属性配置类
private final SmsProperties properties;
//从容器中拿到属性配置类
public SmsAutoConfiguration(SmsProperties properties) {
this.properties = properties;
}/**
* 阿里云短信访问客户端对象注入IOC容器
* @return
* @throws Exception
*/
@Bean
public Client getSmsClient() throws Exception {
Config config = new Config()
.setAccessKeyId(properties.getAccessKeyId())
.setAccessKeySecret(properties.getAccessKeySecret());
// 访问的域名
config.endpoint = properties.getEndpoint();
return new Client(config);
}}
自动配置类的属性类
/**
* @Author: xiang
* @Date: 2021/4/29 17:07
*
* 短信访问客户端属性配置类
*/
@ConfigurationProperties(prefix = "spring.redis.sms")
public class SmsProperties {
private String accessKeyId;
private String accessKeySecret;
// 短信发送请求访问的域名
private String endpoint = "dysmsapi.aliyuncs.com";
public String getAccessKeyId() {
return accessKeyId;
}public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}public String getAccessKeySecret() {
return accessKeySecret;
}public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}public String getEndpoint() {
return endpoint;
}public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
}
方式二:简化方式 直接@Value注入属性值(推荐) 只是:这种方式注释的每一种属性都必须要在配置文件中配置
/**
* @Author: xiang
* @Date: 2021/5/11 20:31
*/
@Configuration
public class SmsConfig {@Value("${spring.redis.sms.access-key-id}")
private String accessKeyId;
@Value("${spring.redis.sms.access-key-secret}")
private String accessKeySecret;
// 短信发送请求访问的域名
private String endpoint = "dysmsapi.aliyuncs.com";
/**
* 阿里云短信访问客户端对象注入IOC容器
* @return
* @throws Exception
*/
@Bean
public Client getSmsClient() throws Exception {
Config config = new Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = endpoint;
System.out.println("-----执行新的SmsConfig-----");
return new Client(config);
}}
属性文件配置 以后直接属性配置文件中配置申请的AccessKeyId与AccessKeySecret就行
阿里云短信通知配置
spring:
redis:
sms:
access-key-id: xxxxxxxxxxxxxx #AccessKeyId
access-key-secret: yyyyyyyyyyyyyyyyyyyyyyy #AccessKeySecret
【Redis|Redis缓存手机验证码实战(包含SpringBoot的灵魂)】注: (想让属性配置文件有自定义属性配置类的提示就得引用依赖)
org.springframework.boot
spring-boot-configuration-processor
true
实战使用
/**
* @Author: xiang
* @Date: 2021/4/28 13:35
*/
@RestController
public class PhoneCodeController { //redis操作模板
private RedisTemplate redisTemplate;
//短信发送客户端
private Client smsClient;
@Autowired
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}@Autowired
public void setSmsClient(Client smsClient) {
this.smsClient = smsClient;
}//发送验证码
@GetMapping("/phone")
public String sendPhoneCode(@RequestParam("phone") String phone) throws Exception {
//生成验证码
int code = (int)((Math.random() * 9 + 1) * 100000);
//同一个电话一天最多发送5次
//保存验证次数
String countKey = "verifyCode"+phone+":count";
Integer count = (Integer) redisTemplate.opsForValue().get(countKey);
if (count == null){
redisTemplate.opsForValue().set(countKey,1,1, TimeUnit.DAYS);
} else if (count < 6){
redisTemplate.opsForValue().increment(countKey);
}else {
return "今天验证次数已用完";
}//阿里云短信服务发送短信
String resultCode = sendCode(phone, code);
if ("OK".equals(resultCode)){
//保存验证码(两分钟有效时间)
String codeKey = "verifyCode"+phone+":code";
redisTemplate.opsForValue().set(codeKey,code,2,TimeUnit.MINUTES);
return "发送成功";
}
return "发送失败";
}//验证
@GetMapping("/phoneCode")
public Boolean verifyCode(@RequestParam("phone") String phone,@RequestParam("code") Integer code){
String codeKey = "verifyCode"+phone+":code";
Integer result = (Integer) redisTemplate.opsForValue().get(codeKey);
if (result.equals(code)) return true;
return false;
//会直接返回错误页面
}private String sendCode(String phone,int code) throws Exception {
SendSmsRequest smsRequest = new SendSmsRequest()
.setPhoneNumbers(phone)
.setSignName("[测试专用]阿里云通信")
.setTemplateCode("[测试专用]阿里云通信测试模版")
.setTemplateParam("{\"code\":"+code+"}");
//需要json样式
//发送请求
SendSmsResponse smsResponse = smsClient.sendSms(smsRequest);
//返回请求状态码
return smsResponse.body.code;
}}
推荐阅读
- Outh2|【OAuth2】三、OAuth2配置解读
- SpringSecurity|springSecurity基础(二)连接数据库的登录
- JAVA|IDEA导出Springboot包(附加本地库)
- SpringBoot|一个依赖搞定 Spring Boot 反爬虫和防止接口盗刷
- Spring系列|Spring系列一(Spring基础篇)
- Java|直播课堂系统02-搭建项目环境
- spring|springboot-自动装配原理
- redis|Redis哨兵-实现Redis高可用
- Java基础|Spring Boot 配置文件加载顺序