Java使用Kaptcha實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼生成器
驗(yàn)證碼生成器
依賴
<!-- 驗(yàn)證碼 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<exclusions>
<exclusion>
<artifactId>javax.servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
</dependency>

首先配置驗(yàn)證碼
@Configuration
public class CaptchaConfig {
@Bean(name = "captchaProducer")
public DefaultKaptcha getKaptchaBean() {
// 驗(yàn)證碼生成器
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
// 創(chuàng)建資源類(lèi)
Properties properties = new Properties();
// 是否有邊框 默認(rèn)為true 我們可以自己設(shè)置yes,no
properties.setProperty(KAPTCHA_BORDER, "yes");
// 驗(yàn)證碼文本字符顏色 默認(rèn)為Color.BLACK
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 驗(yàn)證碼圖片寬度 默認(rèn)為200
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// 驗(yàn)證碼圖片高度 默認(rèn)為50
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// 驗(yàn)證碼文本字符大小 默認(rèn)為40
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
// KAPTCHA_SESSION_KEY 指定保存驗(yàn)證碼文本的 Session 屬性名
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
// 驗(yàn)證碼文本字符長(zhǎng)度 默認(rèn)為5
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// 驗(yàn)證碼文本字體樣式 默認(rèn)為new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 圖片樣式 水紋com.google.code.kaptcha.impl.WaterRipple 魚(yú)眼com.google.code.kaptcha.impl.FishEyeGimpy 陰影com.google.code.kaptcha.impl.ShadowGimpy
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
// 創(chuàng)建配置
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
使用
@Resource(name = "captchaProducer")
private Producer captchaProducer;
/**
* 生成驗(yàn)證碼
*/
@GetMapping("/captchaImage")
public String getCode(HttpServletResponse response) throws IOException {
// 這是文本
String capStr = captchaProducer.createText();
// 這是圖像
BufferedImage image = captchaProducer.createImage(capStr);
// 轉(zhuǎn)換流信息寫(xiě)出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
ImageIO.write(image, "jpg", os);
return Base64.encode(os.toByteArray());
}
計(jì)算驗(yàn)證碼
配置類(lèi)
這里使用自定義的類(lèi)
com.ec.auth.config.KaptchaTextCreator 這是包路徑
// 驗(yàn)證碼文本生成器 properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ec.auth.config.KaptchaTextCreator");
效果

實(shí)現(xiàn)類(lèi)
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
import java.util.Random;
/**
* 驗(yàn)證碼文本生成器
*/
public class KaptchaTextCreator extends DefaultTextCreator {
private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
@Override
public String getText() {
Integer result;
Random random = new Random();
int x = random.nextInt(10);
int y = random.nextInt(10);
StringBuilder suChinese = new StringBuilder();
int randomoperands = (int) Math.round(Math.random() * 2);
if (randomoperands == 0) {
result = x * y;
suChinese.append(CNUMBERS[x]);
suChinese.append("*");
suChinese.append(CNUMBERS[y]);
} else if (randomoperands == 1) {
if (!(x == 0) && y % x == 0) {
result = y / x;
suChinese.append(CNUMBERS[y]);
suChinese.append("/");
suChinese.append(CNUMBERS[x]);
} else {
result = x + y;
suChinese.append(CNUMBERS[x]);
suChinese.append("+");
suChinese.append(CNUMBERS[y]);
}
} else if (randomoperands == 2) {
if (x >= y) {
result = x - y;
suChinese.append(CNUMBERS[x]);
suChinese.append("-");
suChinese.append(CNUMBERS[y]);
} else {
result = y - x;
suChinese.append(CNUMBERS[y]);
suChinese.append("-");
suChinese.append(CNUMBERS[x]);
}
} else {
result = x + y;
suChinese.append(CNUMBERS[x]);
suChinese.append("+");
suChinese.append(CNUMBERS[y]);
}
suChinese.append("=?@").append(result);
return suChinese.toString();
}
}@Bean(name = "captchaProducerMath")
public DefaultKaptcha getKaptchaBeanMath() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 是否有邊框 默認(rèn)為true 我們可以自己設(shè)置yes,no
properties.setProperty(KAPTCHA_BORDER, "yes");
// 邊框顏色 默認(rèn)為Color.BLACK
properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
// 驗(yàn)證碼文本字符顏色 默認(rèn)為Color.BLACK
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
// 驗(yàn)證碼圖片寬度 默認(rèn)為200
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
// 驗(yàn)證碼圖片高度 默認(rèn)為50
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
// 驗(yàn)證碼文本字符大小 默認(rèn)為40
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
// KAPTCHA_SESSION_KEY 指定保存驗(yàn)證碼文本的 Session 屬性名
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
// 驗(yàn)證碼文本生成器
properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ec.auth.config.KaptchaTextCreator");
// 驗(yàn)證碼文本字符間距 默認(rèn)為2
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
// 驗(yàn)證碼文本字符長(zhǎng)度 默認(rèn)為5
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
// 驗(yàn)證碼文本字體樣式 默認(rèn)為new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
// 驗(yàn)證碼噪點(diǎn)顏色 默認(rèn)為Color.BLACK
properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
// 干擾實(shí)現(xiàn)類(lèi)
properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
// 圖片樣式 水紋com.google.code.kaptcha.impl.WaterRipple 魚(yú)眼com.google.code.kaptcha.impl.FishEyeGimpy 陰影com.google.code.kaptcha.impl.ShadowGimpy
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
前端
<div class="login-code">
<img :src="codeUrl" class="login-code-img" @click="getCode" alt=""/>
</div>
const getCode = async () => {
const {img, uuid} = await getCodeImg()
if (captchaOnOff.value) {
codeUrl.value = 'data:image/gif;base64,' + img
}
}
以上就是Java使用Kaptcha實(shí)現(xiàn)簡(jiǎn)單的驗(yàn)證碼生成器的詳細(xì)內(nèi)容,更多關(guān)于Java Kaptcha驗(yàn)證碼生成的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
利用Jackson實(shí)現(xiàn)JSON數(shù)據(jù)的合并
Jackson的功能豐富,安全可靠并且具有比較好的兼容性,這讓程序開(kāi)發(fā)人員可以很方便地實(shí)現(xiàn)JSON 數(shù)據(jù)的相互轉(zhuǎn)換,下面小編就來(lái)和大家介紹一下如何利用Jackson實(shí)現(xiàn)JSON數(shù)據(jù)的合并吧2025-03-03
Java多線程Atomic包操作原子變量與原子類(lèi)詳解
這篇文章主要介紹了Java多線程Atomic包操作原子變量與原子類(lèi)詳解,簡(jiǎn)單介紹了Atomic,同時(shí)涉及java.util.concurrent中的原子變量,Atomic類(lèi)的作用等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
關(guān)于注解式的分布式Elasticsearch的封裝案例
這篇文章主要介紹了關(guān)于注解式的分布式Elasticsearch的封裝案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
Java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)超詳細(xì)教程
這篇文章主要介紹了一個(gè)簡(jiǎn)單的Java學(xué)生信息管理系統(tǒng),使用ArrayList集合存儲(chǔ)學(xué)生對(duì)象信息,并實(shí)現(xiàn)了添加、刪除、修改和查看學(xué)生信息的功能,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01
IDEA實(shí)現(xiàn)一鍵部署項(xiàng)目到服務(wù)器過(guò)程
本文介紹了在阿里云服務(wù)器上通過(guò)開(kāi)放2375端口、配置Docker及IDEA插件,實(shí)現(xiàn)項(xiàng)目打包、編寫(xiě)Dockerfile、構(gòu)建鏡像和容器,并最終通過(guò)瀏覽器訪問(wèn)部署服務(wù)的全過(guò)程2025-10-10
Spring?Boot源碼實(shí)現(xiàn)StopWatch優(yōu)雅統(tǒng)計(jì)耗時(shí)
這篇文章主要為大家介紹了Spring?Boot源碼實(shí)現(xiàn)StopWatch優(yōu)雅統(tǒng)計(jì)耗時(shí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Spring Boot 2.7.8 集成 Thymeleaf的最佳實(shí)踐與常見(jiàn)問(wèn)題
本文詳細(xì)介紹了如何將SpringBoot2.7.8與Thymeleaf集成,從項(xiàng)目依賴到配置文件設(shè)置,再到控制器和模板的創(chuàng)建,以及如何解決常見(jiàn)的集成問(wèn)題,通過(guò)實(shí)際案例,讀者可以快速掌握SpringBoot和Thymeleaf的協(xié)同工作,并解決開(kāi)發(fā)過(guò)程中遇到的問(wèn)題,感興趣的朋友跟隨小編一起看看吧2025-12-12
Java基礎(chǔ)學(xué)習(xí)之ArrayList類(lèi)概述與常用方法
這篇文章主要為大家簡(jiǎn)單的介紹Java中ArrayList類(lèi)的概述、常用方法及存儲(chǔ)字符串并遍歷,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-08-08

