欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot3整合Hutool-captcha實(shí)現(xiàn)圖形驗(yàn)證碼

 更新時(shí)間:2024年11月28日 11:58:12   作者:Harry技術(shù)  
在整合技術(shù)框架的時(shí)候,想找一個(gè)圖形驗(yàn)證碼相關(guān)的框架,看到很多驗(yàn)證碼的maven庫(kù)不再更新了或中央倉(cāng)庫(kù)下載不下來(lái),還需要多引入依賴,后面看到了Hutool圖形驗(yàn)證碼(Hutool-captcha)中對(duì)驗(yàn)證碼的實(shí)現(xiàn),所以本文介紹了SpringBoot3整合Hutool-captcha實(shí)現(xiàn)圖形驗(yàn)證碼

驗(yàn)證碼需求分析:

1. 生成驗(yàn)證碼,點(diǎn)擊圖片可進(jìn)行刷新
2. 輸入驗(yàn)證碼,點(diǎn)擊提交,驗(yàn)證用戶輸入驗(yàn)證碼是否正確

項(xiàng)目創(chuàng)建

首先創(chuàng)建項(xiàng)目這里使用的Spring boot 3 + JDK17,并引入相關(guān)依賴

pom.xml

<properties>
        <java.version>17</java.version>

        <hutool.version>5.8.26</hutool.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-captcha</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-bom</artifactId>
                <version>${hutool.version}</version>
                <type>pom</type>
                <!-- 注意這里是import -->
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

import方式的使用說(shuō)明

如果你想像Spring-Boot一樣引入Hutool,再由子模塊決定用到哪些模塊,你可以在父模塊中加入:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-bom</artifactId>
            <version>${hutool.version}</version>
            <type>pom</type>
            <!-- 注意這里是import -->
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在子模塊中就可以引入自己需要的模塊了:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-captcha</artifactId>
</dependency>

使用import的方式,只會(huì)引入hutool-bom內(nèi)的dependencyManagement的配置,其它配置在這個(gè)引用方式下完全不起作用。

exclude方式

如果你引入的模塊比較多,但是某幾個(gè)模塊沒(méi)用,你可以:

<dependencies>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-bom</artifactId>
        <version>${hutool.version}</version>
        <!-- 加不加這句都能跑,區(qū)別只有是否告警  -->
        <type>pom</type>
        <exclusions>
            <exclusion>
                    <groupId>cn.hutool</groupId>
                    <artifactId>hutool-system</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

這個(gè)配置會(huì)傳遞依賴hutool-bom內(nèi)所有dependencies的內(nèi)容,當(dāng)前hutool-bom內(nèi)的dependencies全部設(shè)置了version,就意味著在maven resolve的時(shí)候hutool-bom內(nèi)就算存在dependencyManagement也不會(huì)產(chǎn)生任何作用。

定義接口:

1. 生成驗(yàn)證碼,并返回
2. 校驗(yàn)驗(yàn)證碼是否正確

接口定義

1.  生成驗(yàn)證碼
[URL]
GET /captcha/getCaptcha
[請(qǐng)求參數(shù)]
[響應(yīng)]
{
    "uuid": "fc2b40825f20470bb4f5d9868b33856f",
    "img": "data:image/png;base64,issaxxxxxxxxgg=="
}

uuid 是為了方便在真實(shí)項(xiàng)目使用中做區(qū)分
2. 校驗(yàn)驗(yàn)證碼是否正確
[URL]
POST /captcha/check
[請(qǐng)求參數(shù)]
{"uuid":"43b4b30bf1134e9f8430507b7babd620","code":""}
[響應(yīng)]
{
   true
}

根據(jù)用戶輸入的驗(yàn)證碼,校驗(yàn)驗(yàn)證碼是否正確,校驗(yàn)成功,返回true;校驗(yàn)失敗,返回false

定義 CaptchaController

@Slf4j
@RestController
@RequestMapping("/captcha")
@AllArgsConstructor
public class CaptchaController {

    private final SysCaptchaService sysCaptchaService;

    /**
     * 生成驗(yàn)證碼
     */
    @GetMapping("/getCaptcha")
    public CaptchaResult getCaptcha(HttpSession session) {
        return sysCaptchaService.getCaptcha(session);
    }

    /**
     * 驗(yàn)證碼校驗(yàn)
     *
     * @param param 驗(yàn)證碼參數(shù)
     */
    @PostMapping("/check")
    public boolean checkCaptcha(@RequestBody CaptchaValidateParam param, HttpSession session) {
        String uuid = param.getUuid();
        String captcha = param.getCode();
        if (StrUtil.isEmpty(uuid) || StrUtil.isEmpty(captcha)) {
            log.error("驗(yàn)證碼參數(shù)不能為空");
            return false;
        }
        log.info("接收到驗(yàn)證碼: uuId:{}, 驗(yàn)證碼:{}", uuid, captcha);
        // 參數(shù)校驗(yàn)
        return sysCaptchaService.validate(uuid, captcha, session);
    }
}

由于當(dāng)用戶輸入驗(yàn)證碼時(shí),我們需要進(jìn)行校驗(yàn),因此,我們需要對(duì)生成的驗(yàn)證碼進(jìn)行存儲(chǔ),同時(shí),需要存儲(chǔ)驗(yàn)證碼的生成時(shí)間,以便判斷驗(yàn)證碼是否超時(shí)

public class Constants {
    public static final String CAPTCHA_CODE = "code";
    public static final String CAPTCHA_UUID = "uuid";
}
  • SysCaptchaService
public interface SysCaptchaService {

    /**
     * 獲取驗(yàn)證碼
     *
     * @param session
     * @return
     */
    CaptchaResult getCaptcha(HttpSession session);

    /**
     * 驗(yàn)證碼效驗(yàn)
     *
     * @param uuid
     * @param code
     * @param session
     * @return
     */
    boolean validate(String uuid, String code, HttpSession session);
}

  • SysCaptchaServiceImpl
@Service
@RequiredArgsConstructor
@Slf4j
public class SysCaptchaServiceImpl implements SysCaptchaService {

    private final CaptchaProperties captchaProperties;
    private final CodeGenerator codeGenerator;
    private final Font captchaFont;


    @Override
    public CaptchaResult getCaptcha(HttpSession session) {


        String captchaType = captchaProperties.getType();
        int width = captchaProperties.getWidth();
        int height = captchaProperties.getHeight();
        int interfereCount = captchaProperties.getInterfereCount();
        int codeLength = captchaProperties.getCode().getLength();

        AbstractCaptcha captcha;
        if (CaptchaTypeEnums.CIRCLE.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createCircleCaptcha(width, height, codeLength, interfereCount);
        } else if (CaptchaTypeEnums.GIF.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createGifCaptcha(width, height, codeLength);
        } else if (CaptchaTypeEnums.LINE.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createLineCaptcha(width, height, codeLength, interfereCount);
        } else if (CaptchaTypeEnums.SHEAR.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createShearCaptcha(width, height, codeLength, interfereCount);
        } else {
            throw new IllegalArgumentException("Invalid captcha type: " + captchaType);
        }
        captcha.setGenerator(codeGenerator);
        captcha.setTextAlpha(captchaProperties.getTextAlpha());
        captcha.setFont(captchaFont);

        String code = captcha.getCode();
        String imageBase64Data = captcha.getImageBase64Data();

        // 驗(yàn)證碼文本緩存至Redis,用于登錄校驗(yàn)
        String uuid = IdUtil.fastSimpleUUID();

        session.setAttribute(Constants.CAPTCHA_CODE, code);
        session.setAttribute(Constants.CAPTCHA_UUID, uuid);

        return CaptchaResult.builder().img(imageBase64Data).uuid(uuid).build();
    }

    @Override
    public boolean validate(String uuid, String code, HttpSession session) {
        // session中獲取驗(yàn)證碼
        String captchaCode = (String) session.getAttribute(Constants.CAPTCHA_CODE);
        return codeGenerator.verify(captchaCode, code);
    }

將用戶輸入的驗(yàn)證碼與存儲(chǔ)在 session 中的驗(yàn)證碼進(jìn)行對(duì)比,判斷其是否相同,若相同且在1min內(nèi),則驗(yàn)證成功

前端代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #app {
            font-family: Avenir, Helvetica, Arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
            margin-top: 60px;
        }

        #inputCaptcha {
            height: 30px;
            vertical-align: middle;
        }

        #verificationCodeImg {
            vertical-align: middle;
        }

        #checkCaptcha {
            height: 40px;
            width: 100px;
            border: 1px solid #000;
            border-radius: 5px;
            margin-left: 10px;
            vertical-align: middle;
        }
    </style>
</head>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>

<body>
<div id="app">
    <h1>{{ message }}</h1>
    <input type="text" v-model="inputCaptcha" id="inputCaptcha">
    <img id="verificationCodeImg" :src="captchaData.img" alt="驗(yàn)證碼" @click="refreshCaptcha" title="看不清?換一張"/>
    <input type="button" value="提交" id="checkCaptcha" @click="checkCaptcha">
</div>

<script type="module">
    import {createApp, ref, onMounted} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

    createApp({
        setup() {
            const message = ref('驗(yàn)證碼校驗(yàn)')
            const inputCaptcha = ref('')
            const captchaData = ref({
                img: '',
                uuid: ''
            })

            const refreshCaptcha = () => {
                $.ajax({
                    url: '/captcha/getCaptcha',
                    type: 'GET',
                    success: function (data) {
                        captchaData.value = data
                    }
                })
            }

            const checkCaptcha = () => {
                const  dataFrom = {
                    uuid: captchaData.value.uuid,
                    code: inputCaptcha.value
                }
                $.ajax({
                    url: '/captcha/check',
                    type: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    data: JSON.stringify(dataFrom),
                    success: function (data) {
                        if (data) {
                            alert('驗(yàn)證碼正確')
                            refreshCaptcha()
                        } else {
                            alert('驗(yàn)證碼錯(cuò)誤')
                            refreshCaptcha()
                        }
                    }
                })
            }

            // 頁(yè)面加載完成后,刷新驗(yàn)證碼
            onMounted(() => {
                refreshCaptcha()
            })

            return {
                message,
                captchaData,
                inputCaptcha,
                refreshCaptcha,
                checkCaptcha
            }
        }
    }).mount('#app')
</script>
</body>
</html>

驗(yàn)證成功:

驗(yàn)證失?。?/p>

為讓驗(yàn)證碼有多樣性,這里將驗(yàn)證的生成放入了application.yml配置文件中,內(nèi)容如下:

# 驗(yàn)證碼配置
captcha:
  # 驗(yàn)證碼類型 circle-圓圈干擾驗(yàn)證碼|gif-Gif驗(yàn)證碼|line-干擾線驗(yàn)證碼|shear-扭曲干擾驗(yàn)證碼
  type: circle
  # 驗(yàn)證碼寬度
  width: 130
  # 驗(yàn)證碼高度
  height: 48
  # 驗(yàn)證碼干擾元素個(gè)數(shù)
  interfere-count: 2
  # 文本透明度(0.0-1.0)
  text-alpha: 0.8
  # 驗(yàn)證碼字符配置
  code:
    # 驗(yàn)證碼字符類型 math-算術(shù)|random-隨機(jī)字符
    type: math
    # 驗(yàn)證碼字符長(zhǎng)度,type=算術(shù)時(shí),表示運(yùn)算位數(shù)(1:個(gè)位數(shù)運(yùn)算 2:十位數(shù)運(yùn)算);type=隨機(jī)字符時(shí),表示字符個(gè)數(shù)
    length: 1
  # 驗(yàn)證碼字體
  font:
    # 字體名稱 Dialog|DialogInput|Monospaced|Serif|SansSerif
    name: SansSerif
    # 字體樣式 0-普通|1-粗體|2-斜體
    weight: 1
    # 字體大小
    size: 20
  # 驗(yàn)證碼有效期(秒)
  expire-seconds: 120

以上就是SpringBoot3整合Hutool-captcha實(shí)現(xiàn)圖形驗(yàn)證碼的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot3 Hutool-captcha驗(yàn)證碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java Scanner類及其方法使用圖解

    Java Scanner類及其方法使用圖解

    這篇文章主要介紹了Java Scanner類及其方法使用圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • IDEA配置碼云Gitee的使用詳解

    IDEA配置碼云Gitee的使用詳解

    這篇文章主要介紹了IDEA配置碼云Gitee的使用,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java8新特性stream和parallelStream區(qū)別

    Java8新特性stream和parallelStream區(qū)別

    這篇文章主要介紹了Java8新特性stream和parallelStream區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • FastJson踩坑:@JsonField在反序列化時(shí)失效的解決

    FastJson踩坑:@JsonField在反序列化時(shí)失效的解決

    這篇文章主要介紹了FastJson踩坑:@JsonField在反序列化時(shí)失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 深入解析Jdk8中Stream流的使用讓你脫離for循環(huán)

    深入解析Jdk8中Stream流的使用讓你脫離for循環(huán)

    這篇文章主要介紹了Jdk8中Stream流的使用,讓你脫離for循環(huán),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • spring boot空屬性賦值問(wèn)題與aspect日志實(shí)現(xiàn)方法

    spring boot空屬性賦值問(wèn)題與aspect日志實(shí)現(xiàn)方法

    這篇文章主要介紹了spring boot空屬性賦值問(wèn)題與aspect日志實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • restTemplate未設(shè)置連接數(shù)導(dǎo)致服務(wù)雪崩問(wèn)題以及解決

    restTemplate未設(shè)置連接數(shù)導(dǎo)致服務(wù)雪崩問(wèn)題以及解決

    面對(duì)線上問(wèn)題,仔細(xì)分析原因,及時(shí)調(diào)整配置,能有效解決問(wèn)題,本文詳細(xì)描述了線上遇到流量突增引發(fā)的問(wèn)題,通過(guò)查看代碼和連接池信息,分析出問(wèn)題的原因是連接池滿了,連接池大小配置不足以應(yīng)對(duì)大并發(fā)流量,通過(guò)調(diào)整連接池大小配置
    2024-10-10
  • SpringWebMVC的常用注解及應(yīng)用分層架構(gòu)詳解

    SpringWebMVC的常用注解及應(yīng)用分層架構(gòu)詳解

    這篇文章主要介紹了SpringWebMVC的常用注解及應(yīng)用分層架構(gòu),SpringWebMVC是基于ServletAPI構(gòu)建的原始Web框架,從?開(kāi)始就包含在Spring框架中,感興趣的朋友可以參考下
    2024-05-05
  • SpringBoot集成MQTT實(shí)現(xiàn)交互服務(wù)通信

    SpringBoot集成MQTT實(shí)現(xiàn)交互服務(wù)通信

    MQTT非常適用于物聯(lián)網(wǎng)領(lǐng)域,本文主要介紹了SpringBoot集成MQTT實(shí)現(xiàn)交互服務(wù)通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • RocketMQ的四種常用消息隊(duì)列及代碼演示

    RocketMQ的四種常用消息隊(duì)列及代碼演示

    這篇文章主要介紹了RocketMQ的四種常用消息隊(duì)列及代碼演示,普通消息隊(duì)列是最基本的一種消息隊(duì)列,可以按照先進(jìn)先出(FIFO)的順序存儲(chǔ)消息,并且可以被多個(gè)消費(fèi)者同時(shí)消費(fèi),可以通過(guò)在生產(chǎn)者端指定主題名稱和標(biāo)簽來(lái)創(chuàng)建普通消息隊(duì)列,需要的朋友可以參考下
    2024-01-01

最新評(píng)論