您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)java實(shí)現(xiàn)發(fā)送驗(yàn)證碼短信功能的方法的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
功能需求:
1、后臺(tái)隨機(jī)產(chǎn)生4個(gè)字符
2、1分鐘以內(nèi)只能發(fā)送1次驗(yàn)證碼
3、超過1分鐘,但在5分鐘以內(nèi),發(fā)送的驗(yàn)證碼依然是第一次產(chǎn)生的驗(yàn)證碼字符
4、超過了5分鐘以后,產(chǎn)生全新的驗(yàn)證碼
前端使用什么框架先不管
依賴配置
短信依賴包 redis配置,因?yàn)轵?yàn)證碼和手機(jī)號(hào)存儲(chǔ)在redis中
短信平臺(tái)使用的建網(wǎng) sms ,http://www.smschinese.cn/ 可以免費(fèi)使用5條 測(cè)試即可
注意:配置接口的 賬戶名 和 密鑰 每個(gè)人是不同的,復(fù)制過去記得更改
短信依賴包
<!--短信jar包--> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency>
redis jar包
<!--redis jar 包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
使用redis前,要先配置連接,在application.properties配置
# redis 屬性信息 ## redis數(shù)據(jù)庫索引(默認(rèn)為0) spring.redis.database=0 ## redis服務(wù)器地址 spring.redis.host=localhost ## redis服務(wù)器連接端口 spring.redis.port=6379 ## redis服務(wù)器連接密碼(默認(rèn)為空) ## spring.redis.password=123456 ## 連接池最大連接數(shù)(使用負(fù)值表示沒有限制) spring.redis.jedis.pool.max-active=8 ## 連接池中的最大空閑連接 spring.redis.jedis.pool.max-idle=8 ## 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制) spring.redis.jedis.pool.max-wait=-1ms ## 連接池中的最小空閑連接 spring.redis.jedis.pool.min-idle=0
創(chuàng)建一個(gè)工具類 StrUtils.getComplexRandomString ()// 獲取隨機(jī)字符 位數(shù)自己輸入
import java.util.ArrayList; import java.util.List; import java.util.Random; /** * @author yaohuaipeng * @date 2018/10/26-16:16 */ public class StrUtils { /** * 把逗號(hào)分隔的字符串轉(zhuǎn)換字符串?dāng)?shù)組 * * @param str * @return */ public static String[] splitStr2StrArr(String str,String split) { if (str != null && !str.equals("")) { return str.split(split); } return null; } /** * 把逗號(hào)分隔字符串轉(zhuǎn)換List的Long * * @param str * @return */ public static List<Long> splitStr2LongArr(String str) { String[] strings = splitStr2StrArr(str,","); if (strings == null) return null; List<Long> result = new ArrayList<>(); for (String string : strings) { result.add(Long.parseLong(string)); } return result; } /** * 把逗號(hào)分隔字符串轉(zhuǎn)換List的Long * * @param str * @return */ public static List<Long> splitStr2LongArr(String str,String split) { String[] strings = splitStr2StrArr(str,split); if (strings == null) return null; List<Long> result = new ArrayList<>(); for (String string : strings) { result.add(Long.parseLong(string)); } return result; } public static String getRandomString(int length) { String str = "0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(10); sb.append(str.charAt(number)); } return sb.toString(); } public static String getComplexRandomString(int length) { String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(62); sb.append(str.charAt(number)); } return sb.toString(); } public static String convertPropertiesToHtml(String properties){ //1:容量:6:32GB_4:樣式:12:塑料殼 StringBuilder sBuilder = new StringBuilder(); String[] propArr = properties.split("_"); for (String props : propArr) { String[] valueArr = props.split(":"); sBuilder.append(valueArr[1]).append(":").append(valueArr[3]).append("<br>"); } return sBuilder.toString(); } }
創(chuàng)建短信發(fā)送類 配置接口,其它類調(diào)用這個(gè)類的send方法傳入手機(jī)號(hào)和發(fā)送內(nèi)容即可
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.PostMethod; import java.io.IOException; public class SendMsgUtils { private static final String UID = "amazingwest";//這是建網(wǎng)SMS 上的登陸賬號(hào) private static final String KEY = "d41d8cd98f00b204e980"; //這是密鑰 /** * 手機(jī)發(fā)送短信 * @param phone 手機(jī)號(hào)碼 * @param context 發(fā)送短信內(nèi)容 */ public static void send(String phone, String context) { PostMethod post = null; try { //創(chuàng)建Http客戶端 HttpClient client = new HttpClient(); //創(chuàng)建一個(gè)post方法 post = new PostMethod("http://utf8.api.smschinese.cn"); //添加請(qǐng)求頭信息 post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf8");//在頭文件中設(shè)置轉(zhuǎn)碼 NameValuePair[] data = {new NameValuePair("Uid", UID), new NameValuePair("Key", KEY), new NameValuePair("smsMob", phone), new NameValuePair("smsText", context)}; //設(shè)置請(qǐng)求體 post.setRequestBody(data); //執(zhí)行post方法 client.executeMethod(post); //獲取響應(yīng)頭信息 Header[] headers = post.getResponseHeaders(); //獲取狀態(tài)碼 int statusCode = post.getStatusCode(); System.out.println("statusCode:" + statusCode); //循環(huán)打印頭信息 for (Header h : headers) { System.out.println(h.toString()); } //獲取相應(yīng)體 String result = new String(post.getResponseBodyAsString().getBytes("utf8")); System.out.println(result); //打印返回消息狀態(tài) } catch (IOException e) { e.printStackTrace(); } finally { if (post != null) { //關(guān)閉資源 post.releaseConnection(); } } } }
創(chuàng)建注冊(cè)常量類,主要用來區(qū)分驗(yàn)證碼是用來注冊(cè)還是登陸或者找回密碼
/** * 驗(yàn)證碼常量 */ public class VerificationConstant { //用戶注冊(cè)常量 public static final String USER_REG = "user_reg"; }
前臺(tái)點(diǎn)擊發(fā)送驗(yàn)證碼 首先要考慮多個(gè)用戶同時(shí)注冊(cè),key值不能寫死
首先根據(jù)手機(jī)號(hào)加注冊(cè)標(biāo)識(shí)(KEY)判斷redis中值value是否存在,不存在就創(chuàng)建一個(gè)鍵,key為手機(jī)號(hào)+加注冊(cè)標(biāo)識(shí),
判斷時(shí)間,就是創(chuàng)建redis鍵值對(duì)的時(shí)候就,value會(huì)加上一個(gè)當(dāng)前時(shí)間戳,取value第一次創(chuàng)建的時(shí)間會(huì)分割value 拿當(dāng)前時(shí)間戳減去第一次創(chuàng)建的時(shí)間戳就能得出具體的時(shí)間
第一次創(chuàng)建鍵值 設(shè)置鍵的存活時(shí)間為5分鐘 300秒
發(fā)送驗(yàn)證碼短信,前端傳來手機(jī)號(hào)碼,在這里進(jìn)行業(yè)務(wù)邏輯判斷 不需要判斷手機(jī)號(hào)是否注冊(cè),這是其它類的事情 使用redisTemplate 就必須得 引入redis jar包
StrUtils.getComplexRandomString(4) 這就是上面創(chuàng)建的工具類中的一個(gè)方法,創(chuàng)建4位字符的隨機(jī)數(shù),
StringUtils.isEmpty 是 import org.springframework.util.StringUtils 別弄錯(cuò)了
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.concurrent.TimeUnit; @Service public class VerificationCodeServiceImpl implements IVerificationCodeService { @Autowired private RedisTemplate redisTemplate; /** * 發(fā)送注冊(cè)驗(yàn)證碼 * 驗(yàn)證碼需求: * 1.后臺(tái)隨機(jī)產(chǎn)生4個(gè)字符 * 2.1分鐘以內(nèi)只能發(fā)送1次驗(yàn)證碼 * 3.超過1分鐘,但在5分鐘以內(nèi),發(fā)送的驗(yàn)證碼依然是第一次產(chǎn)生的驗(yàn)證碼字符 * 4.超過了5分鐘以后,產(chǎn)生全新的驗(yàn)證碼 * @return */ @Override public void sendRegisterVerificationCode(String phone) throws CustomException { //隨機(jī)產(chǎn)生4個(gè)字符 String value = StrUtils.getComplexRandomString(4); //在redis中通過key獲取對(duì)應(yīng)的值 value:時(shí)間戳 String valueCode = (String) redisTemplate.opsForValue().get(phone + ":" + VerificationConstant.USER_REG); //如果不為空,就意味著驗(yàn)證碼沒有過期,依然是在5分鐘以內(nèi) if(!StringUtils.isEmpty(valueCode)){ //開始時(shí)間戳 String beginTimer = valueCode.split(":")[1]; if(System.currentTimeMillis()-Long.valueOf(beginTimer)<=60*1000){ //自定義異常,自己創(chuàng)建一個(gè)就可以了 throw new CustomException("親!一分鐘以內(nèi)不能發(fā)送多次驗(yàn)證碼!!"); } //證明是超過了1分鐘,但依然在5分鐘以內(nèi),還是用之前的驗(yàn)證碼 value = valueCode.split(":")[0]; } //存儲(chǔ)redis中,設(shè)置有效期是5分鐘 k=phone:USER_REG v= value:時(shí)間戳 // RedisUtil.set(phone:USER_REG, value:System.currentTimeMillis(), 5MIN); redisTemplate.opsForValue().set(phone + ":" + VerificationConstant.USER_REG, value + ":" + System.currentTimeMillis(), 5, TimeUnit.MINUTES); //發(fā)送手機(jī)驗(yàn)證碼 String context = "尊敬的用戶,您的驗(yàn)證碼為:" + value + ",請(qǐng)您在5分鐘以內(nèi)完成注冊(cè)!!"; //發(fā)送短信 // SendMsgUtils.send(phone, context); System.out.println(context); } }
完成。
感謝各位的閱讀!關(guān)于“java實(shí)現(xiàn)發(fā)送驗(yàn)證碼短信功能的方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。