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

基于Java實(shí)現(xiàn)圖形驗(yàn)證碼工具類

 更新時(shí)間:2024年11月20日 09:39:34   作者:一線大碼  
這篇文章主要為大家詳細(xì)介紹了如何基于Java實(shí)現(xiàn)圖形驗(yàn)證碼工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

工具類:

package com.example.demo.util;

import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;

/**
 * 驗(yàn)證碼工具類
 *
 * @author wangbo
 * @since 2024/10/29
 */
@Slf4j
public class CaptchaGeneratorUtil {

    private CaptchaGeneratorUtil() {
        // ...
    }

    public static void main(String[] args) throws IOException {
        // 生成4位隨機(jī)數(shù)字驗(yàn)證碼
        String text = generateRandomCode();
        // 創(chuàng)建驗(yàn)證碼圖片
        BufferedImage image = createImage(text);
        // 保存圖片到文件
        ImageIO.write(image, "png", new File("captcha.png"));
    }

    private static final SecureRandom RANDOM = new SecureRandom();

    /**
     * 生成4位隨機(jī)數(shù)字字母驗(yàn)證碼
     */
    public static String generateRandomCode() {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            int i1 = RANDOM.nextInt(3);
            if (i1 == 0) {
                code.append((char) (RANDOM.nextInt(26) + 65));
            } else if (i1 == 1) {
                code.append((char) (RANDOM.nextInt(26) + 97));
            } else {
                code.append(RANDOM.nextInt(10));
            }
        }
        log.info("生成的驗(yàn)證碼文本 text = {}", code);
        return code.toString();
    }

    /**
     * 創(chuàng)建驗(yàn)證碼圖片
     */
    public static BufferedImage createImage(String text) {
        log.info("待生成驗(yàn)證碼圖片的文本 text = {}", text);
        int width = 75;
        int height = 25;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 使用Graphics2D以獲得更好的圖形控制
        Graphics2D g2d = image.createGraphics();

        try {
            // 設(shè)置背景顏色
            g2d.setColor(new Color(0xDCDCDC));
            g2d.fillRect(0, 0, width, height);

            // 設(shè)置字體和顏色
            g2d.setFont(new Font("Arial", Font.BOLD, 20));
            g2d.setColor(new Color(0x004000));

            // 確保文本不會(huì)超出圖像邊界
            FontMetrics fm = g2d.getFontMetrics();
            int textWidth = fm.stringWidth(text);
            // 居中文本
            int x = (width - textWidth) / 2;
            // 居中文本(基線對(duì)齊)
            int y = (height - fm.getHeight()) / 2 + fm.getAscent();

            g2d.drawString(text, x, y);

            // 添加噪聲線
            for (int i = 0; i < 5; i++) {
                g2d.setColor(new Color(RANDOM.nextInt(255), RANDOM.nextInt(255), RANDOM.nextInt(255)));
                g2d.drawLine(RANDOM.nextInt(width), RANDOM.nextInt(height), RANDOM.nextInt(width), RANDOM.nextInt(height));
            }

            // 設(shè)置渲染提示以提高圖像質(zhì)量(可選)
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        } finally {
            // 確保在try塊之后釋放Graphics2D資源
            g2d.dispose();
        }

        return image;
    }

    private static final String CAPTCHA_PREFIX = "captcha:";

    public static String generateCaptchaRedisKey(String key) {
        return CAPTCHA_PREFIX + key;
    }
}

生成圖片驗(yàn)證碼接口(該接口無需權(quán)限校驗(yàn)):

/**
 * 生成圖片驗(yàn)證碼
 *
 * @param key UUID字符串
 */
@GetMapping("/captcha/generator/{key}")
public void captchaGenerator(@PathVariable("key") String key, HttpServletResponse response) throws BaseException {
    userService.captchaGenerator(key, response);
}
public void captchaGenerator(String key, HttpServletResponse response) throws BaseException {
    //查看key的驗(yàn)證碼是否已存在
    String captchaRedisKey = CaptchaGeneratorUtil.generateCaptchaRedisKey(key);
    boolean hasKey = Boolean.TRUE.equals(redisTemplate.hasKey(captchaRedisKey));
    if (hasKey) {
        throw new BaseException(ErrorCode.USER_KEY_REPETITION);
    }
    String captcha = CaptchaGeneratorUtil.generateRandomCode();
    BufferedImage image = CaptchaGeneratorUtil.createImage(captcha);
    //設(shè)置驗(yàn)證碼,有效期1分鐘
    redisTemplate.opsForValue().set(captchaRedisKey, captcha, 60L, TimeUnit.SECONDS);
    response.setContentType("image/jpeg");
    try (ServletOutputStream out = response.getOutputStream()) {
        ImageIO.write(image, "JPEG", out);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

登錄接口或者其他涉及驗(yàn)證碼的接口進(jìn)行驗(yàn)證碼校驗(yàn):

//校驗(yàn)驗(yàn)證碼
String key = loginPage.getKey();
String captcha = loginPage.getCaptcha();
if (StringUtils.isNullOrEmpty(key) || StringUtils.isNullOrEmpty(captcha)) {
    throw new BaseException(ErrorCode.USER_KEY_OR_CAPTCHA_NOT_FOUND);
}
String captchaRedisKey = CaptchaGeneratorUtil.generateCaptchaRedisKey(key);
String redisCaptcha = redisTemplate.opsForValue().get(captchaRedisKey);
if (StringUtils.isNullOrEmpty(redisCaptcha) || !captcha.equalsIgnoreCase(redisCaptcha)) {
    throw new BaseException(ErrorCode.USER_CAPTCHA_ERROR);
} else {
    //刪除驗(yàn)證碼緩存
    redisTemplate.delete(captchaRedisKey);
}

到此這篇關(guān)于基于Java實(shí)現(xiàn)圖形驗(yàn)證碼工具類的文章就介紹到這了,更多相關(guān)Java圖形驗(yàn)證碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)網(wǎng)頁解析示例

    java實(shí)現(xiàn)網(wǎng)頁解析示例

    這篇文章主要介紹了java實(shí)現(xiàn)網(wǎng)頁解析示例,需要的朋友可以參考下
    2014-04-04
  • Maven setting.xml配置文件詳解

    Maven setting.xml配置文件詳解

    本篇文章主要介紹了Maven setting.xml 配置文件詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • Springboot攔截器如何獲取@RequestBody參數(shù)

    Springboot攔截器如何獲取@RequestBody參數(shù)

    這篇文章主要介紹了Springboot攔截器如何獲取@RequestBody參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring之從橋接方法到JVM方法調(diào)用解讀

    Spring之從橋接方法到JVM方法調(diào)用解讀

    這篇文章主要介紹了Spring之從橋接方法到JVM方法調(diào)用解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Springboot使用JustAuth實(shí)現(xiàn)各種第三方登陸

    Springboot使用JustAuth實(shí)現(xiàn)各種第三方登陸

    本文主要介紹了Springboot使用JustAuth實(shí)現(xiàn)各種第三方登陸,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 使用Java?Executors創(chuàng)建線程池的9種方法

    使用Java?Executors創(chuàng)建線程池的9種方法

    文章主要介紹了?Java?中Executors類創(chuàng)建線程池的?9?種方法,每種方法都詳細(xì)闡述了實(shí)現(xiàn)原理、源代碼分析、參數(shù)解釋、實(shí)現(xiàn)過程、特性和使用場(chǎng)景,感興趣的小伙伴跟著小編一起來看看吧
    2024-11-11
  • Spring?boot?處理大文件上傳完整代碼

    Spring?boot?處理大文件上傳完整代碼

    這篇文章主要介紹了Spring?boot?處理大文件上傳,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 由@NotNull注解引出的關(guān)于Java空指針的控制

    由@NotNull注解引出的關(guān)于Java空指針的控制

    這是一些很容易學(xué)會(huì)的簡(jiǎn)單技術(shù),但是對(duì)于代碼質(zhì)量和健壯性來說確實(shí)很重要。以我的經(jīng)驗(yàn),僅是第一個(gè)小技巧就已經(jīng)對(duì)改進(jìn)代碼質(zhì)量具有很大的作用了
    2016-09-09
  • SpringBoot異步調(diào)用方法并接收返回值

    SpringBoot異步調(diào)用方法并接收返回值

    這篇文章主要為大家詳細(xì)介紹了SpringBoot異步調(diào)用方法并接收返回值,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 統(tǒng)一建模語言_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    統(tǒng)一建模語言_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了統(tǒng)一建模語言的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧
    2017-06-06

最新評(píng)論