Java實現(xiàn)短信驗證碼服務(wù)的完整代碼示例
首先這里使用的是阿里云的短信服務(wù)。
package com.wzy.util;;
import cn.hutool.captcha.generator.RandomGenerator;
import com.aliyun.dysmsapi20170525.Client;
import com.wzy.entity.Ali;
import org.springframework.stereotype.Component;
/**
* @Author: 顧安
* @Description:
* @Date: Create in 17:30 2024/7/23
*/
@Component
public class SendMsgUtil {
/**
* 使用AK&SK初始化賬號Client
* @return Client
* @throws Exception
*/
private static Ali ali;
public SendMsgUtil(Ali ali) {
this.ali = ali;
}
public static Client createClient() throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// 必填,請確保代碼運行環(huán)境設(shè)置了環(huán)境變量 ALIBABA_CLOUD_ACCESS_KEY_ID。
.setAccessKeyId(ali.getAccessKeyId())
// 必填,請確保代碼運行環(huán)境設(shè)置了環(huán)境變量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
.setAccessKeySecret(ali.getAccessKeySecret());
// Endpoint 請參考 https://api.aliyun.com/product/Dysmsapi
config.endpoint = "dysmsapi.aliyuncs.com";
return new Client(config);
}
/* *
* API 相關(guān)
* @return OpenApi.Params*/
public static com.aliyun.teaopenapi.models.Params createApiInfo() throws Exception {
com.aliyun.teaopenapi.models.Params params = new com.aliyun.teaopenapi.models.Params()
// 接口名稱
.setAction("SendSms")
// 接口版本
.setVersion("2017-05-25")
// 接口協(xié)議
.setProtocol("HTTPS")
// 接口 HTTP 方法
.setMethod("POST")
.setAuthType("AK")
.setStyle("RPC")
// 接口 PATH
.setPathname("/")
// 接口請求體內(nèi)容格式
.setReqBodyType("json")
// 接口響應(yīng)體內(nèi)容格式
.setBodyType("json");
return params;
}
public static String sendCode(String phone) throws Exception {
com.aliyun.teaopenapi.Client client = createClient();
com.aliyun.teaopenapi.models.Params params = createApiInfo();
String code="123456";
// query params
java.util.Map<String, Object> queries = new java.util.HashMap<>();
queries.put("PhoneNumbers", phone);
queries.put("SignName", ali.getSignName());
queries.put("TemplateCode", ali.getTemplateCode()); //您正在申請手機注冊,驗證碼為:$[code],5分鐘內(nèi)有效!
queries.put("TemplateParam", "{\"code\":\""+codes()+"\"}");
// runtime options
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
com.aliyun.teaopenapi.models.OpenApiRequest request = new com.aliyun.teaopenapi.models.OpenApiRequest()
.setQuery(com.aliyun.openapiutil.Client.query(queries));
// 復(fù)制代碼運行請自行打印 API 的返回值
// 返回值為 Map 類型,可從 Map 中獲得三類數(shù)據(jù):響應(yīng)體 body、響應(yīng)頭 headers、HTTP 返回的狀態(tài)碼 statusCode。
client.callApi(params, request, runtime);
return codes();
}
public static String codes(){
// 自定義純數(shù)字的驗證碼(隨機4位數(shù)字,可重復(fù))
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
return String.valueOf(randomGenerator);
}
// public static String code(){
// return String.valueOf(ThreadLocalRandom.current().nextInt(100000,1000000));
// }
}上面的一些屬性沒有直接寫到代碼中,而是模擬真實的開發(fā)場景,寫入application.yml配置文件中,通過定義一個類,然后指定配置文件,在阿里配置類中注入改實體類對象。如下圖所示
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ConfigurationProperties("ali.msg")
public class Ali {
private String accessKeyId;
private String accessKeySecret;
private String signName;
private String templateCode;
}
然后需要隨機生成數(shù)字,我這里也使得是hutool工具,需要加入該工具的jar包
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>該工具包含各種場景的工具,滿足開發(fā)需求的很多場景,大家可以學(xué)習(xí)一下,隨機生成的代碼如下:
public static String codes(){
// 自定義純數(shù)字的驗證碼(隨機4位數(shù)字,可重復(fù))
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
return String.valueOf(randomGenerator);
}
生成一個從0到9隨機組成的4位數(shù)。
然后就可以開始編寫我們的真實開發(fā)環(huán)境的發(fā)送驗證碼
@GetMapping("/send")
public R sentMsg(String phone){
//判斷前端傳過來的手機號是否正確
if (phone.equals("166x786xxxxx")){
//判斷驗證碼是否已發(fā)送,防止惡意發(fā)送
if (redisTemplate.hasKey("code::"+phone)){
return new R(200,"請不要頻繁點擊",null);
}
try {
//調(diào)用阿里云的接口并拿到前端傳來的手機號
String code = SendMsgUtil.sendCode(phone);
//把驗證碼存入到redis緩存中并設(shè)置過期時間
redisTemplate.opsForValue().set("code::"+phone,code,5, TimeUnit.MINUTES);
return new R(200,"發(fā)送成功",null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return new R(200,"發(fā)送失敗",null);
}@PostMapping("/login")
public R login(@RequestBody LoginVo loginVo){
//拿到緩存中的驗證碼
String code = redisTemplate.opsForValue().get("code::" + loginVo.getPhone());
//拿到緩存中的手機號
String phone = loginVo.getPhone();
//判斷手機號是否正確
if (phone.equals("16627865460")){
//判斷驗證碼是否為空是否正確
if (StringUtils.hasText(loginVo.getCode())&&loginVo.getCode().equals(code)){
//刪除緩存中的驗證碼,防止惡意登入
redisTemplate.delete("code::" + phone);
return new R(200,"登入成功",null);
}else {
return new R(500,"登入失敗",null);
}
}
return new R(500,"登入失敗",null);
}總結(jié)
到此這篇關(guān)于Java實現(xiàn)短信驗證碼服務(wù)的文章就介紹到這了,更多相關(guān)Java實現(xiàn)短信驗證碼服務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot動態(tài)生成接口實現(xiàn)流程示例講解
最近遇到一個需求,需要在程序運行過程中,可以動態(tài)新增接口,自定義接口參數(shù)名稱,基本類型,以及請求方法,請求頭等等。通過幾天的研究,找到了我需要的解決方案2023-01-01
Spring中的FactoryBean與BeanFactory詳細解析
這篇文章主要介紹了Spring中的FactoryBean與BeanFactory詳細解析,在Spring框架中,FactoryBean和BeanFactory是兩個關(guān)鍵的接口,用于創(chuàng)建和管理對象實例,它們在Spring的IoC(Inversion of Control,控制反轉(zhuǎn))容器中發(fā)揮著重要的作用,需要的朋友可以參考下2023-11-11
SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置問題及解決方法
這篇文章主要介紹了SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置,我們可以通過自定義配置數(shù)據(jù)庫配置類來解決這個問題,方式有很多,不同的業(yè)務(wù)采用的方式也不同,下面我簡單的介紹我們項目的使用的方法2022-06-06

