SpringBoot實(shí)現(xiàn)圖形驗(yàn)證碼生成的方法
我們其實(shí)很經(jīng)常看到,登錄一些網(wǎng)站其實(shí)是需要驗(yàn)證碼的,本文給大家介紹了SpringBoot實(shí)現(xiàn)圖形驗(yàn)證碼生成的方法,需要的朋友可以參考下
這是一個(gè)登錄頁(yè)面,在登錄的最后一部,很多時(shí)候都會(huì)讓我們輸入驗(yàn)證碼,今天就來講講如何在SpringBoot中實(shí)現(xiàn)圖形驗(yàn)證碼的生成。驗(yàn)證碼的生成是一個(gè)非常常用的工具類,網(wǎng)上有很多寫法。

手寫驗(yàn)證碼
首先說明一下,這里的手寫,并不是博主自己手寫的,而是在GitHub中看到過一個(gè)項(xiàng)目,項(xiàng)目中有涉及到一個(gè)驗(yàn)證碼的源碼,感覺還不錯(cuò)。
新建驗(yàn)證碼工具類
驗(yàn)證碼工具類
public class Code {
public static final String RANDOMCODEKEY = "ValidateCode";
//將圖片存放到Session中的key
private Random random = new Random();//生成隨機(jī)數(shù)
private String randomString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//圖片中隨機(jī)產(chǎn)生的字母或數(shù)字
private int width = 80;//圖片寬
private int height = 26;//圖片高
private int lineSize = 40;//干擾線數(shù)量
private int stringNum = 4;//隨機(jī)產(chǎn)生字符數(shù)量
//獲得字體
private Font getFont(){
return new Font("Fixedsys",Font.CENTER_BASELINE,18);
}
//獲得隨機(jī)顏色值
private Color getRandColor(int fc,int bc){
if(fc > 255) {
fc = 255;
}
if(bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc-fc-16);
int g = fc + random.nextInt(bc-fc-14);
int b = fc + random.nextInt(bc-fc-18);
return new Color(r,g,b);
}
/*
* 返回隨機(jī)的字符
*/
private String getRandomString(int num){
return String.valueOf(randomString.charAt(num));
}
/*
* 繪制字符串
*/
private String drawString(Graphics g, String randomString, int i){
g.setFont(getFont());
g.setColor(new Color(random.nextInt(101),random.nextInt(111),random.nextInt(121)));
String rand = String.valueOf(getRandomString(random.nextInt(this.randomString.length())));
randomString += rand;
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(rand, 13 * i, 16);
return randomString;
}
/*
* 繪制干擾線
*/
private void drawLine(Graphics g){
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
g.drawLine(x, y, x + xl, y + yl);
}
//核心方法:生成隨機(jī)驗(yàn)證碼,并返回
public void getValidateCode(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();//產(chǎn)生Image對(duì)象的Graphics對(duì)象,改對(duì)象可以在圖像上進(jìn)行各種繪制操作
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,18));
g.setColor(getRandColor(110, 133));
//繪制干擾線
for(int i = 0;i <= lineSize; i++){
drawLine(g);
}
//繪制隨機(jī)字符
String randomString = "";
for(int i = 1; i <= stringNum; i++){
randomString = drawString(g, randomString, i);
}
//將生成的隨機(jī)字符串裝進(jìn)Session作用域
session.removeAttribute(RANDOMCODEKEY);
session.setAttribute(RANDOMCODEKEY, randomString);
System.out.println(randomString);//輸出生成的隨機(jī)字符串
g.dispose();//關(guān)閉窗體,釋放資源
try {
ImageIO.write(image, "JPEG", response.getOutputStream());//將內(nèi)存中的圖片通過流動(dòng)形式輸出到客戶端
} catch (Exception e) {
e.printStackTrace();
}
}
}
在SpringBoot項(xiàng)目中新建一個(gè)util包,用于存放工具類,這樣一個(gè)驗(yàn)證碼工具類就寫好了。
Controller中調(diào)用
工具類寫好后,就可以在Controller中調(diào)用
@GetMapping("/checkCode2")
public void checkcode2(HttpServletRequest request, HttpServletResponse response){
response.setContentType("image/jpeg");
response.setDateHeader("Expires",0);
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
//引用驗(yàn)證碼工具類,生成驗(yàn)證碼
Code code=new Code();
code.getValidateCode(request,response);
}
@GetMapping("/checkCode2"): 這是一個(gè)Spring MVC注解,表示當(dāng)客戶端發(fā)送一個(gè)GET請(qǐng)求到/checkCode2路徑時(shí),將調(diào)用checkcode2方法。public void checkcode2(HttpServletRequest request, HttpServletResponse response): 這是一個(gè)控制器方法,接收HttpServletRequest和HttpServletResponse對(duì)象作為參數(shù),用于處理HTTP請(qǐng)求和響應(yīng)。response.setContentType("image/jpeg");: 設(shè)置響應(yīng)的內(nèi)容類型為JPEG格式的圖片。response.setDateHeader("Expires",0);: 設(shè)置響應(yīng)頭Expires為0,表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容。response.setHeader("Pragma","no-cache");: 設(shè)置響應(yīng)頭Pragma為no-cache,指示瀏覽器不要緩存頁(yè)面內(nèi)容。response.setHeader("Cache-Control","no-cache");: 設(shè)置響應(yīng)頭Cache-Control為no-cache,進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容。Code code=new Code();: 創(chuàng)建一個(gè)Code類的實(shí)例。code.getValidateCode(request,response);: 調(diào)用Code實(shí)例的getValidateCode方法,生成驗(yàn)證碼并將其寫入響應(yīng)中。
Apifox中驗(yàn)證

Hutool圖形驗(yàn)證碼
Hutool官網(wǎng):https://www.hutool.cn/docs/#/
正如官網(wǎng)簡(jiǎn)介所言,Hutool是一個(gè)小而全的Java工具類庫(kù),它提供了很多常用的工具類,幾乎包羅萬(wàn)象。

今天我們使用的是hutool-captcha(圖形驗(yàn)證碼)。
引入依賴
這里使用的是Maven,如果是其他的項(xiàng)目構(gòu)建工具,請(qǐng)參考文檔。
單獨(dú)引入圖形驗(yàn)證碼的依賴模塊
<!-- 添加圖形驗(yàn)證碼依賴 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>5.8.6</version>
</dependency>
當(dāng)然,為了方便,也可以按照文檔中的方法,引入所有模塊。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>

LineCaptcha:線段干擾的驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//調(diào)用Hutool的圖形驗(yàn)證碼
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38, 5, 5);
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38, 5, 5);
定義圖形驗(yàn)證碼的長(zhǎng)、寬、驗(yàn)證碼字符數(shù)、干擾線寬度LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38)
定義圖形驗(yàn)證碼的長(zhǎng)、寬
上面這兩種寫法都是可以的

CircleCaptcha:圓形干擾驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//調(diào)用Hutool的圖形驗(yàn)證碼
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38, 5, 20);
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38, 5, 20);
定義圖形驗(yàn)證碼的長(zhǎng)、寬、驗(yàn)證碼字符數(shù)、干擾?個(gè)數(shù)CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38);
定義圖形驗(yàn)證碼的長(zhǎng)、寬
圓形干擾驗(yàn)證碼同樣兩種寫法。

ShearCaptcha:扭曲干擾驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//調(diào)用Hutool的圖形驗(yàn)證碼
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38,5,5);
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38,5,5);
定義圖形驗(yàn)證碼的長(zhǎng)、寬、驗(yàn)證碼字符數(shù)、干擾線寬度ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38);
定義圖形驗(yàn)證碼的長(zhǎng)、寬

GifCaptcha:GIF驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//調(diào)用Hutool的圖形驗(yàn)證碼
GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38,5);
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}
GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38,5);
定義GIF驗(yàn)證碼的長(zhǎng)、寬、驗(yàn)證碼字符數(shù)GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38);
定義GIF驗(yàn)證碼的長(zhǎng)、寬
大家可以去試試,這里截不出那種Gif的效果


自定義驗(yàn)證碼

純數(shù)字驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
// 自定義純數(shù)字的驗(yàn)證碼(隨機(jī)4位數(shù)字,可重復(fù))
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);
captcha.setGenerator(randomGenerator);
// 重新生成code
captcha.createCode();
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}

當(dāng)然除了LineCaptcha,CircleCaptcha,GifCaptcha,ShearCaptcha都是可以的
純字母驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
// 自定義純數(shù)字的驗(yàn)證碼(隨機(jī)4位數(shù)字,可重復(fù))
RandomGenerator randomGenerator = new RandomGenerator("abcdefghijklmnopqrstuvwyzx", 4);
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100);
captcha.setGenerator(randomGenerator);
// 重新生成code
captcha.createCode();
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}

四則運(yùn)算驗(yàn)證碼
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
// 自定義驗(yàn)證碼內(nèi)容為四則運(yùn)算方式
captcha.setGenerator(new MathGenerator());
// 重新生成code
captcha.createCode();
//指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Pragma","no-cache");
//進(jìn)一步指示瀏覽器不要緩存頁(yè)面內(nèi)容
response.setHeader("Cache-Control","no-cache");
//表示頁(yè)面內(nèi)容已過期,瀏覽器應(yīng)當(dāng)每次都從服務(wù)器獲取最新內(nèi)容
response.setDateHeader("Expires",0);
//表示返回的內(nèi)容為JPEG格式的圖片
response.setContentType("image/jpeg");
//圖片驗(yàn)證碼寫出
captcha.write(response.getOutputStream());
//關(guān)閉流
response.getOutputStream().close();
}

以上就是SpringBoot實(shí)現(xiàn)圖形驗(yàn)證碼生成的方法的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot圖形驗(yàn)證碼生成的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Java整合RocketMQ實(shí)現(xiàn)生產(chǎn)消費(fèi)詳解
這篇文章主要介紹了關(guān)于Java整合RocketMQ實(shí)現(xiàn)生產(chǎn)消費(fèi)詳解,RocketMQ作為一款純java、分布式、隊(duì)列模型的開源消息中間件,支持事務(wù)消息、順序消息、批量消息、定時(shí)消息、消息回溯等,需要的朋友可以參考下2023-05-05
springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid)
這篇文章主要介紹了springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
MyBatis解決Update動(dòng)態(tài)SQL逗號(hào)的問題
這篇文章主要介紹了MyBatis解決Update動(dòng)態(tài)SQL逗號(hào)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
IntelliJ?IDEA快速查詢maven依賴關(guān)系圖文教程
Maven提供了來查看依賴關(guān)系,而IDE往往提供了更加便利的方式,比如Eclipse或者IDEA都有類似的功能,下面這篇文章主要給大家介紹了關(guān)于IntelliJ?IDEA快速查詢maven依賴關(guān)系的相關(guān)資料,需要的朋友可以參考下2023-11-11
java?常規(guī)輪詢長(zhǎng)輪詢Long?polling實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了java?常規(guī)輪詢長(zhǎng)輪詢Long?polling實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
JPA原生SQL實(shí)現(xiàn)增刪改查的示例詳解
JPA除了對(duì)JPQL提供支持外,還對(duì)原生SQL語(yǔ)句也提供了支持。本文將利用生SQL實(shí)現(xiàn)增刪改查功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-09-09
java構(gòu)建Stream流的多種方式總結(jié)
Java?8引入了Stream流作為一項(xiàng)新的特性,它是用來處理集合數(shù)據(jù)的一種函數(shù)式編程方式,本文為大家整理了多種java構(gòu)建Stream流的方式,希望對(duì)大家有所幫助2023-11-11

