基于Hutool的圖片驗(yàn)證碼功能模塊實(shí)現(xiàn)
簡(jiǎn)介
Hutool是一個(gè)小而全的Java工具類庫(kù),通過(guò)靜態(tài)方法封裝,降低相關(guān)API的學(xué)習(xí)成本,提高工作效率,使Java擁有函數(shù)式語(yǔ)言般的優(yōu)雅,讓Java語(yǔ)言也可以“甜甜的”。
Hutool中的工具方法來(lái)自每個(gè)用戶的精雕細(xì)琢,它涵蓋了Java開(kāi)發(fā)底層代碼中的方方面面,它既是大型項(xiàng)目開(kāi)發(fā)中解決小問(wèn)題的利器,也是小型項(xiàng)目中的效率擔(dān)當(dāng);
Hutool是項(xiàng)目中“util”包友好的替代,它節(jié)省了開(kāi)發(fā)人員對(duì)項(xiàng)目中公用類和公用工具方法的封裝時(shí)間,使開(kāi)發(fā)專注于業(yè)務(wù),同時(shí)可以最大限度的避免封裝不完善帶來(lái)的bug。
Hutool名稱的由來(lái)
Hutool = Hu + tool,是原公司項(xiàng)目底層代碼剝離后的開(kāi)源庫(kù),“Hu”是公司名稱的表示,tool表示工具。Hutool諧音“糊涂”,一方面簡(jiǎn)潔易懂,一方面寓意“難得糊涂”。
基于Hutool的圖片驗(yàn)證碼功能模塊實(shí)現(xiàn)
1.背景
為了提高系統(tǒng)的安全性,防止接口被暴力刷新,驗(yàn)證碼是個(gè)好的手段,圖片驗(yàn)證碼沒(méi)有短信驗(yàn)證碼的費(fèi)用,其是個(gè)人開(kāi)發(fā)者學(xué)習(xí)的重點(diǎn)。
2.方案設(shè)計(jì)
2.1 方案步驟
- 引入Hutool工具集
- 安裝Redis
- 接入Reids配置
2.2 Hutool工具類引入
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.8</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.7.0</version> </dependency>
2.3 安裝Redis
默認(rèn)端口:6379 - 下載連接 https://github.com/tporadowski/redis/releases - 解壓 - 雙擊redis-server.exe啟動(dòng)服務(wù)端 - 雙擊redis-cli.exe啟動(dòng)客戶端連接服務(wù)端
2.4 接入Reids配置
在ClassPath(或者src/main/resources)的config目錄下下新建redis.setting
#------------------------------------------------------------------------------- # Redis客戶端配置樣例 # 每一個(gè)分組代表一個(gè)Redis實(shí)例 # 無(wú)分組的Pool配置為所有分組的共用配置,如果分組自己定義Pool配置,則覆蓋共用配置 # 池配置來(lái)自于:https://www.cnblogs.com/jklk/p/7095067.html #------------------------------------------------------------------------------- #----- 默認(rèn)(公有)配置 # 地址,默認(rèn)localhost host = localhost # 端口,默認(rèn)6379 port = 6379 # 超時(shí),默認(rèn)2000 timeout = 2000 # 連接超時(shí),默認(rèn)timeout connectionTimeout = 2000 # 讀取超時(shí),默認(rèn)timeout soTimeout = 2000 # 密碼,默認(rèn)無(wú) # 如果提示密碼錯(cuò)誤換成:Auth = password = # 數(shù)據(jù)庫(kù)序號(hào),默認(rèn)0 database = 0 # 客戶端名,默認(rèn)"Hutool" clientName = Hutool # SSL連接,默認(rèn)false ssl = false; #----- 自定義分組的連接 [custom] # 地址,默認(rèn)localhost host = localhost # 連接耗盡時(shí)是否阻塞, false報(bào)異常,ture阻塞直到超時(shí), 默認(rèn)true BlockWhenExhausted = true; # 設(shè)置的逐出策略類名, 默認(rèn)DefaultEvictionPolicy(當(dāng)連接超過(guò)最大空閑時(shí)間,或連接數(shù)超過(guò)最大空閑連接數(shù)) evictionPolicyClassName = org.apache.commons.pool2.impl.DefaultEvictionPolicy # 是否啟用pool的jmx管理功能, 默認(rèn)true jmxEnabled = true; # 是否啟用后進(jìn)先出, 默認(rèn)true lifo = true; # 最大空閑連接數(shù), 默認(rèn)8個(gè) maxIdle = 8 # 最小空閑連接數(shù), 默認(rèn)0 minIdle = 0 # 最大連接數(shù), 默認(rèn)8個(gè) maxTotal = 8 # 獲取連接時(shí)的最大等待毫秒數(shù)(如果設(shè)置為阻塞時(shí)BlockWhenExhausted),如果超時(shí)就拋異常, 小于零:阻塞不確定的時(shí)間, 默認(rèn)-1 maxWaitMillis = -1 # 逐出連接的最小空閑時(shí)間 默認(rèn)1800000毫秒(30分鐘) minEvictableIdleTimeMillis = 1800000 # 每次逐出檢查時(shí) 逐出的最大數(shù)目 如果為負(fù)數(shù)就是 : 1/abs(n), 默認(rèn)3 numTestsPerEvictionRun = 3; # 對(duì)象空閑多久后逐出, 當(dāng)空閑時(shí)間>該值 且 空閑連接>最大空閑數(shù) 時(shí)直接逐出,不再根據(jù)MinEvictableIdleTimeMillis判斷 (默認(rèn)逐出策略) SoftMinEvictableIdleTimeMillis = 1800000 # 在獲取連接的時(shí)候檢查有效性, 默認(rèn)false testOnBorrow = false # 在空閑時(shí)檢查有效性, 默認(rèn)false testWhileIdle = false # 逐出掃描的時(shí)間間隔(毫秒) 如果為負(fù)數(shù),則不運(yùn)行逐出線程, 默認(rèn)-1 timeBetweenEvictionRunsMillis = -1
2.5 方案交互圖
client server redis uuid generate: Image code JSON)(code, time) setnx(uid, JSON) save result send result opt [send option] uid + code get uid JSON(code, time) check code true? check result opt [check option] client server redis
3.模塊編寫(xiě)
VerificationImageCodeService.java
package com.example.basePro.sevice; import com.example.basePro.bean.dto.Result; import com.example.basePro.bean.model.ImageCode; /** * @Author: * @Date: 2022/10/16 * @Description: */ public interface VerificationImageCodeService { /** * 生成圖片驗(yàn)證碼對(duì)應(yīng)的編碼 * @param uuid 用戶id * @return 圖片的base64編碼 */ String generateImageCode(String uuid); /** * 驗(yàn)證圖片驗(yàn)證碼內(nèi)容 * @param uuid 用戶id * @param code 驗(yàn)證碼內(nèi)容 * @return 驗(yàn)證結(jié)果 */ Result<String> chechImageCode(String uuid, String code) throws Exception; }
package com.example.basePro.sevice.Impl; import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.LineCaptcha; import cn.hutool.db.nosql.redis.RedisDS; import cn.hutool.json.JSONUtil; import com.example.basePro.bean.dto.Result; import com.example.basePro.bean.model.ImageCode; import com.example.basePro.sevice.VerificationImageCodeService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import redis.clients.jedis.Jedis; /** * @Author: * @Date: 2022/10/16 * @Description: */ @Slf4j @Service public class VerificationImageCodeServiceImpl implements VerificationImageCodeService { /** * 驗(yàn)證碼失效時(shí)間 */ @Value("${constants.expire.second: 600}") private Long expireSecond; @Override public String generateImageCode(String uuid) { String key = uuid; Jedis jedis = RedisDS.create().getJedis(); LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 50); log.info("image code is {}", lineCaptcha.getCode()); jedis.del(key); // 存入緩存 ImageCode imageCode = ImageCode.builder() .code(lineCaptcha.getCode()) .createTime(System.currentTimeMillis()) .build(); jedis.setex(key, expireSecond, JSONUtil.toJsonStr(imageCode)); // 瀏覽器中輸入 data:image/png;base64, + base64, 即可顯示圖片 return lineCaptcha.getImageBase64(); } @Override public Result<String> chechImageCode(String uuid, String code) throws Exception { String key = uuid; Jedis jedis = RedisDS.create().getJedis(); // 獲取緩存中數(shù)據(jù) String cache = jedis.get(key); ImageCode imageCode = JSONUtil.toBean(cache, ImageCode.class); if (StringUtils.isEmpty(cache)){ throw new Exception("驗(yàn)證碼已過(guò)期"); } // 驗(yàn)證碼不匹配 if(!code.equals(imageCode.getCode())){ throw new Exception("驗(yàn)證碼錯(cuò)誤"); } jedis.del(key); return Result.success("驗(yàn)證成功"); } }
4.接口測(cè)試
訪問(wèn)獲取圖片驗(yàn)證碼接口:
http://localhost:8080/captcha/getcode?uuid=123456
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
在瀏覽器中輸入:
data:image/png;base64,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
訪問(wèn)驗(yàn)證接口:
http://localhost:8080/captcha/check?uuid=123456&code=****
5.參考文獻(xiàn)
到此這篇關(guān)于基于Hutool的圖片驗(yàn)證碼功能模塊實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Hutool圖片驗(yàn)證碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從0開(kāi)始教你開(kāi)發(fā)一個(gè)springboot應(yīng)用
這篇文章主要為大家介紹了從0開(kāi)始開(kāi)發(fā)一個(gè)springboot應(yīng)用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Java輕松使用工具類實(shí)現(xiàn)獲取MP3音頻時(shí)長(zhǎng)
在Java中,工具類定義了一組公共方法,這篇文章將介紹Java中使用工具類來(lái)獲取一個(gè)MP3音頻文件的時(shí)間長(zhǎng)度,感興趣的同學(xué)繼續(xù)往下閱讀吧2021-10-10Spring根據(jù)URL參數(shù)進(jìn)行路由的方法詳解
這篇文章主要給大家介紹了關(guān)于Spring根據(jù)URL參數(shù)進(jìn)行路由的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起來(lái)看看吧。2017-12-12Java在線打開(kāi)word文檔并強(qiáng)制留痕的方法
在本篇文章里小編給讀者們分享的是關(guān)于Java在線打開(kāi)word文檔并強(qiáng)制留痕的方法,對(duì)此有需要的朋友們可以學(xué)習(xí)下。2020-01-01Spring boot2X Consul如何通過(guò)RestTemplate實(shí)現(xiàn)服務(wù)調(diào)用
這篇文章主要介紹了spring boot2X Consul如何通過(guò)RestTemplate實(shí)現(xiàn)服務(wù)調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12Java數(shù)據(jù)結(jié)構(gòu)專題解析之棧和隊(duì)列的實(shí)現(xiàn)
從數(shù)據(jù)結(jié)構(gòu)的定義看,棧和隊(duì)列也是一種線性表。其不同之處在于棧和隊(duì)列的相關(guān)運(yùn)算具有特殊性,只是線性表相關(guān)運(yùn)算的一個(gè)子集。更準(zhǔn)確的說(shuō),一般線性表的插入、刪除運(yùn)算不受限制,而棧和隊(duì)列上的插入刪除運(yùn)算均受某種特殊限制。因此,棧和隊(duì)列也稱作操作受限的線性表2021-10-10Java中Date數(shù)據(jù)類型的數(shù)值轉(zhuǎn)換方式
這篇文章主要介紹了Java中Date數(shù)據(jù)類型的數(shù)值轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07Mybatis利用分頁(yè)插件PageHelper快速實(shí)現(xiàn)分頁(yè)查詢
如果你也在用MyBatis,建議嘗試該分頁(yè)插件,這一定是最方便使用的分頁(yè)插件,這篇文章主要給大家介紹了關(guān)于Mybatis利用分頁(yè)插件PageHelper快速實(shí)現(xiàn)分頁(yè)查詢的相關(guān)資料,PageHelper是一個(gè)Mybatis的分頁(yè)插件,負(fù)責(zé)將已經(jīng)寫(xiě)好的sql語(yǔ)句,進(jìn)行分頁(yè)加工,需要的朋友可以參考下2021-08-08Springboot實(shí)現(xiàn)圖片上傳功能的示例代碼
本篇文章主要介紹了SpringBoot如何實(shí)現(xiàn)圖片上傳功能,文中通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-09-09