手机验证码
pom文件
添加依赖(阿里云通讯)
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
配置文件
在properties文件中添加accessKeyId,accessKeySecret值
# 在控制台可以找到
send.accessKeyId=***
send.accessKeySecret=***
配置文件类
@Data
@Component
@ConfigurationProperties(ignoreUnknownFields = false, prefix = "send")
public class SendProperties {
private String accessKeyId;
private String accessKeySecret;
}
手机号码验证类
@Component
public class PhoneFormatCheckUtils {
/**
* 大陆号码或香港号码均可
*/
public boolean isPhoneLegal(String str)throws PatternSyntaxException {
return isChinaPhoneLegal(str) || isHKPhoneLegal(str);
}
/**
* 大陆手机号码11位数,匹配格式:前三位固定格式+后8位任意数
* 此方法中前三位格式有:
* 13+任意数
* 15+除4的任意数
* 18+除1和4的任意数
* 17+除9的任意数
* 147
*/
public boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
String regExp = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$";
Pattern p = Pattern.compile(regExp);
Matcher m = p.matcher(str);
return m.matches();
}
/**
* 香港手机号码8位数,5|6|8|9开头+7位任意数
*/
public boolean isHKPhoneLegal(String str)throws PatternSyntaxException {
String regExp = "^(5|6|8|9)\\d{7}$";
Pattern p = Pattern.compile(regExp);
Matcher m = p.matcher(str);
return m.matches();
}
}
验证码发送工具类(阿里云通讯)
@Component
public class SendUtils {
@Autowired
SendProperties sendProperties;
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi";
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com";
// TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
// static final String accessKeyId = "***";
//static final String accessKeySecret = "***";
public SendSmsResponse sendSms(String telephone,String code) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", sendProperties.getAccessKeyId(), sendProperties.getAccessKeySecret());
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
//必填:待发送手机号
request.setPhoneNumbers(telephone);
//必填:短信签名-可在短信控制台中找到
request.setSignName("***");
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode("***");
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
request.setTemplateParam("{\"code\":" + code + "}");
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
return sendSmsResponse;
}
//根据发送短信成功后返回的bizId 和手机号查询明细
public QuerySendDetailsResponse querySendDetails(String bizId,String phone) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", sendProperties.getAccessKeyId(),sendProperties.getAccessKeySecret());
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
//必填-号码
request.setPhoneNumber(phone);
//可选-流水号
request.setBizId(bizId);
//必填-发送日期 支持30天内记录查询,格式yyyyMMdd
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
request.setSendDate(ft.format(new Date()));
//必填-页大小
request.setPageSize(10L);
//必填-当前页码从1开始计数
request.setCurrentPage(1L);
//hint 此处可能会抛出异常,注意catch
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
return querySendDetailsResponse;
}
/* public static void main(String[] args) throws ClientException, InterruptedException {
//发短信
SendSmsResponse response = sendSms();
System.out.println("短信接口返回的数据----------------");
System.out.println("Code=" + response.getCode());
System.out.println("Message=" + response.getMessage());
System.out.println("RequestId=" + response.getRequestId());
System.out.println("BizId=" + response.getBizId());
Thread.sleep(3000L);
//查明细
if(response.getCode() != null && response.getCode().equals("OK")) {
QuerySendDetailsResponse querySendDetailsResponse = querySendDetails(response.getBizId());
System.out.println("短信明细查询接口返回数据----------------");
System.out.println("Code=" + querySendDetailsResponse.getCode());
System.out.println("Message=" + querySendDetailsResponse.getMessage());
int i = 0;
for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs())
{
System.out.println("SmsSendDetailDTO["+i+"]:");
System.out.println("Content=" + smsSendDetailDTO.getContent());
System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());
System.out.println("OutId=" + smsSendDetailDTO.getOutId());
System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());
System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());
System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());
System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());
System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());
}
System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());
System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());
}
}*/
}
实例
controller层
@RestController
@RequestMapping(value = "/***r")
@Api(tags = "newCustomer",description = "接口")
public class NewCustomerController {
@Autowired
RedisTemplate redisTemplate;
@Autowired
NewCustomerService newCustomerService;
@Autowired
WebTokenAuthenticationService tokenAuthenticationService;
@PostMapping(value = "/getCode")
@ApiOperation(value = "获取验证码",notes = "获取验证码",httpMethod = "POST")
public Response getCode(String phone){
return new Response.Builder()
.withResult(newCustomerService.getCode(phone))
.build();
}
@PostMapping(value = "/codeSignin")
@ApiOperation(value = "使用验证码登录", notes = "使用验证码登录", httpMethod = "POST")
public Response codeSignin(@Valid @RequestBody SigninCodeDTO signinCodeDTO, BindingResult result) throws NoCodeException, CodeException, FailureException {
if (result.hasErrors()) {
return new Response.Builder()
.withError(result.getAllErrors().get(0).getDefaultMessage())
.build();
}
CustomerPO customerPO = newCustomerService.codeSignup(signinCodeDTO);
redisTemplate.delete(signinCodeDTO.getPhone());
if (customerPO == null) {
return new Response.Builder()
.withError("请输入正确的手机号!")
.build();
}
return new Response.Builder()
.withResult(tokenAuthenticationService.generateToken(customerPO))
.build();
}
}
service
@Slf4j
@Service
public class NewCustomerService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private NewCustomerDAO customerDAO;
@Autowired
RedisTemplate redisTemplate;
@Autowired
private SendUtils sendUtils;
@Autowired
PhoneFormatCheckUtils phoneFormatCheckUtils;
public Result getCode(String phone) {
//验证手机号格式
if (!phoneFormatCheckUtils.isChinaPhoneLegal(phone)){
return new Result(false,"手机号格式不正确");
}
try {
//生成验证码
String code =(long)(Math.random() * 1000000) + "";
//调用工具类发送短信
sendUtils.sendSms(phone, code);
//将验证码存入redis用于登录验证,并设置失效时长
redisTemplate.boundValueOps(phone).set(code,5,TimeUnit.MINUTES);
return new Result(true,"验证码发送成功");
} catch (ClientException e) {
e.printStackTrace();
return new Result(false,"验证码发送失败");
}
}
public CustomerPO codeSignup(SigninCodeDTO signinCodeDTO) throws NoCodeException, CodeException, FailureException {
//根据手机号查询数据库,判断该手机号是否存在于用户数据库
CustomerPO customerPO = customerDAO.getManager(signinCodeDTO.getPhone());
CustomerPO customer = customerDAO.getCustomer(signinCodeDTO.getPhone());
if (customerPO==null && customer==null){
return null;
}
if (signinCodeDTO.getCode() == null){
throw new NoCodeException();
}
String code = String.valueOf(redisTemplate.boundValueOps(signinCodeDTO.getPhone()).get());
if ("null".equals(code)){
throw new FailureException();
}
if (customerPO != null){
if (code.equals(signinCodeDTO.getCode())){
return customerPO;
}else {
throw new CodeException();
}
}
if (customer != null){
if (code.equals(signinCodeDTO.getCode())){
return customer;
}else {
throw new CodeException();
}
}
return null;
}
}
dao层
public interface NewCustomerDAO {
/**
* 获取用户信息
*
* @param phone
* @return
*/
CustomerPO getManager(@Param("phone") String phone);
/**
* 获取用户信息
*
* @param phone
* @return
*/
CustomerPO getCustomer(@Param("phone") String phone);
}
mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hrzn.dao.app.NewCustomerDAO">
<select id="getManager" resultType="com.hrzn.dao.custompo.CustomerPO">
SELECT aid,cid,username,password,mail,telephone,created,updated,name,type FROM customer_accounts WHERE telephone = #{phone};
</select>
<select id="getCustomer" resultType="com.hrzn.dao.custompo.CustomerPO">
SELECT cid,username,password,mail,telephone,created,updated,name,type FROM customer WHERE telephone = #{phone};
</select>
</mapper>
结果返回类
Result类
@Data
public class Result{
private boolean success;
private boolean flag;
private String message;
public Result(boolean success, String message) {
super();
this.success=success;
this.flag = success;
this.message = message;
}
}
Response类
@Data
public class Response {
public Response() {
this.errcode = 0;
}
/**
* error code
*/
private int errcode;
/**
* error message
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private String errmsg;
@JsonInclude(JsonInclude.Include.NON_NULL)
private Object result;
public static class Builder {
private Response mResponse;
public Builder withResult(Object e) {
if (e == null) {
this.withSuccess(false);
return this;
}
if (mResponse == null) {
mResponse = new Response();
}
mResponse.setErrcode(0);
mResponse.setResult(e);
return this;
}
public Builder withExcelResult(Object e) {
if (e == null) {
this.withSuccess(true);
return this;
}
if (mResponse == null) {
mResponse = new Response();
}
mResponse.setErrcode(-1);
mResponse.setResult(e);
return this;
}
public Builder withSuccess(boolean success) {
if (mResponse == null) {
mResponse = new Response();
}
if (success) {
mResponse.setErrcode(0);
mResponse.setErrmsg("ok");
} else {
mResponse.setErrcode(-1);
mResponse.setErrmsg("fail");
}
return this;
}
public Builder withError(Exception e) {
if (mResponse == null) {
mResponse = new Response();
}
mResponse.setErrcode(-1);
if (e.getMessage() == null) {
mResponse.setErrmsg(e.toString());
} else {
mResponse.setErrmsg(e.getMessage());
}
return this;
}
public Builder withError(String errmsg) {
if (mResponse == null) {
mResponse = new Response();
}
mResponse.setErrcode(-1);
mResponse.setErrmsg(errmsg);
return this;
}
public Response build() {
if (mResponse == null) {
mResponse = new Response();
}
return mResponse;
}
}
}