在现代应用中,发送短信验证码是一个常见的功能,特别是在用户注册、登录、密码重置等场景。本文将介绍如何使用Spring Boot和Redis实现短信发送功能,包括短信验证码的生成、发送和验证。
首先,我们需要创建一个Spring Boot项目,并引入相关依赖。可以使用Spring Initializr生成项目,也可以手动添加依赖。
在 pom.xml
文件中添加以下依赖:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- SMS Service API (假设使用阿里云短信服务) -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
<!-- 其他依赖 -->
</dependencies>
在 application.yml
文件中配置Redis连接信息:
spring:
redis:
host: localhost
port: 6379
database: 0
timeout: 5000
jedis:
pool:
max-active: 20
max-idle: 10
min-idle: 5
这里假设使用阿里云短信服务。需要配置阿里云的访问密钥和短信模板。
aliyun:
sms:
access-key-id: your-access-key-id
access-key-secret: your-access-key-secret
sign-name: your-sign-name
template-code: your-template-code
创建一个 SmsService
类,用于发送短信验证码。
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class SmsService {
@Value("${aliyun.sms.access-key-id}")
private String accessKeyId;
@Value("${aliyun.sms.access-key-secret}")
private String accessKeySecret;
@Value("${aliyun.sms.sign-name}")
private String signName;
@Value("${aliyun.sms.template-code}")
private String templateCode;
private IAcsClient initClient() {
DefaultProfile profile = DefaultProfile.getProfile("default", accessKeyId, accessKeySecret);
return new DefaultAcsClient(profile);
}
public void sendSms(String phoneNumber, String code) throws ClientException {
IAcsClient client = initClient();
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("PhoneNumbers", phoneNumber);
request.putQueryParameter("SignName", signName);
request.putQueryParameter("TemplateCode", templateCode);
request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
}
}
创建一个控制器 SmsController
,用于生成验证码并发送短信。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
public class SmsController {
@Autowired
private SmsService smsService;
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping("/sendSms")
public String sendSms(@RequestParam String phoneNumber) {
String code = generateCode();
try {
smsService.sendSms(phoneNumber, code);
redisTemplate.opsForValue().set(phoneNumber, code, 5, TimeUnit.MINUTES);
return "SMS sent successfully";
} catch (Exception e) {
e.printStackTrace();
return "Failed to send SMS";
}
}
private String generateCode() {
return String.valueOf((int) (Math.random() * 900000 + 100000));
}
}
在 SmsController
中添加一个方法用于验证验证码。
@GetMapping("/verifyCode")
public String verifyCode(@RequestParam String phoneNumber, @RequestParam String code) {
String storedCode = redisTemplate.opsForValue().get(phoneNumber);
if (storedCode != null && storedCode.equals(code)) {
return "Verification successful";
} else {
return "Verification failed";
}
}
package com.example.sms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import java.util.concurrent.TimeUnit;
@Service
class SmsService {
@Value("${aliyun.sms.access-key-id}")
private String accessKeyId;
@Value("${aliyun.sms.access-key-secret}")
private String accessKeySecret;
@Value("${aliyun.sms.sign-name}")
private String signName;
@Value("${aliyun.sms.template-code}")
private String templateCode;
private IAcsClient initClient() {
DefaultProfile profile = DefaultProfile.getProfile("default", accessKeyId, accessKeySecret);
return new DefaultAcsClient(profile);
}
public void sendSms(String phoneNumber, String code) throws ClientException {
IAcsClient client = initClient();
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("PhoneNumbers", phoneNumber);
request.putQueryParameter("SignName", signName);
request.putQueryParameter("TemplateCode", templateCode);
request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
}
}
@RestController
class SmsController {
@Autowired
private SmsService smsService;
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping("/sendSms")
public String sendSms(@RequestParam String phoneNumber) {
String code = generateCode();
try {
smsService.sendSms(phoneNumber, code);
redisTemplate.opsForValue().set(phoneNumber, code, 5, TimeUnit.MINUTES);
return "SMS sent successfully";
} catch (Exception e) {
e.printStackTrace();
return "Failed to send SMS";
}
}
@GetMapping("/verifyCode")
public String verifyCode(@RequestParam String phoneNumber, @RequestParam String code) {
String storedCode = redisTemplate.opsForValue().get(phoneNumber);
if (storedCode != null && storedCode.equals(code)) {
return "Verification successful";
} else {
return "Verification failed";
}
}
private String generateCode() {
return String.valueOf((int) (Math.random() * 900000 + 100000));
}
}
通过本文的介绍,我们成功地使用Spring Boot和Redis实现了短信发送和验证码验证功能。该方案通过Redis存储验证码,提高了系统的性能和可靠性,适用于各种需要短信验证的场景。
思维导图:Spring Boot + Redis 发送短信
graph TD;
A[Spring Boot + Redis 发送短信] --> B[项目初始化]
B --> B1[添加依赖]
B --> B2[配置Redis]
A --> C[实现短信发送功能]
C --> C1[配置短信服务]
C --> C2[创建短信服务类]
C --> C3[生成验证码并存储到Redis]
C --> C4[验证短信验证码]
A --> D[总结]
通过上述步骤,开发者可以轻松实现一个具备短信发送和验证功能的系统,增强应用的安全性和用户
体验。