当前位置: 首页 > news >正文

【SpringBoot】你不能不会的SpringBoot图形验证码生成

文章目录

  • 手写验证码
    • 新建验证码工具类
    • Controller中调用
    • Apifox中验证
  • Hutool图形验证码
    • 引入依赖
    • LineCaptcha:线段干扰的验证码
    • CircleCaptcha:圆形干扰验证码
    • ShearCaptcha:扭曲干扰验证码
    • GifCaptcha:GIF验证码
    • 自定义验证码
      • 纯数字验证码
      • 纯字母验证码
      • 四则运算验证码

这是一个登录页面,在登录的最后一部,很多时候都会让我们输入验证码,今天就来讲讲如何在SpringBoot中实现图形验证码的生成。验证码的生成是一个非常常用的工具类,网上有很多写法。
在这里插入图片描述

手写验证码

首先说明一下,这里的手写,并不是博主自己手写的,而是在GitHub中看到过一个项目,项目中有涉及到一个验证码的源码,感觉还不错。

新建验证码工具类

验证码工具类

public class Code {
    public static final String RANDOMCODEKEY = "ValidateCode";
    //将图片存放到Session中的key

    private Random random = new Random();//生成随机数

    private String randomString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    //图片中随机产生的字母或数字

    private int width = 80;//图片宽
    private int height = 26;//图片高
    private int lineSize = 40;//干扰线数量
    private int stringNum = 4;//随机产生字符数量

    //获得字体
    private Font getFont(){
        return new Font("Fixedsys",Font.CENTER_BASELINE,18);
    }

    //获得随机颜色值
    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);
    }

    /*
     * 返回随机的字符
     */
    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);
    }

    //核心方法:生成随机验证码,并返回
    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();//产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        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);
        }

        //绘制随机字符
        String randomString = "";
        for(int i = 1; i <= stringNum; i++){
            randomString = drawString(g, randomString, i);
        }

        //将生成的随机字符串装进Session作用域
        session.removeAttribute(RANDOMCODEKEY);
        session.setAttribute(RANDOMCODEKEY, randomString);
        System.out.println(randomString);//输出生成的随机字符串

        g.dispose();//关闭窗体,释放资源
        try {
            ImageIO.write(image, "JPEG", response.getOutputStream());//将内存中的图片通过流动形式输出到客户端
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

SpringBoot项目中新建一个util包,用于存放工具类,这样一个验证码工具类就写好了。

Controller中调用

工具类写好后,就可以在Controller中调用

    @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");
        //引用验证码工具类,生成验证码
        Code code=new Code();
        code.getValidateCode(request,response);
    }
  • @GetMapping("/checkCode2"): 这是一个Spring MVC注解,表示当客户端发送一个GET请求到/checkCode2路径时,将调用checkcode2方法。
  • public void checkcode2(HttpServletRequest request, HttpServletResponse response): 这是一个控制器方法,接收HttpServletRequest和HttpServletResponse对象作为参数,用于处理HTTP请求和响应。
  • response.setContentType("image/jpeg");: 设置响应的内容类型为JPEG格式的图片。
  • response.setDateHeader("Expires",0);: 设置响应头Expires为0,表示页面内容已过期,浏览器应当每次都从服务器获取最新内容。
  • response.setHeader("Pragma","no-cache");: 设置响应头Pragma为no-cache,指示浏览器不要缓存页面内容。
  • response.setHeader("Cache-Control","no-cache");: 设置响应头Cache-Control为no-cache,进一步指示浏览器不要缓存页面内容。
  • Code code=new Code();: 创建一个Code类的实例。
  • code.getValidateCode(request,response);: 调用Code实例的getValidateCode方法,生成验证码并将其写入响应中。

Apifox中验证

在这里插入图片描述


Hutool图形验证码

Hutool官网:https://www.hutool.cn/docs/#/
正如官网简介所言,Hutool是一个小而全的Java工具类库,它提供了很多常用的工具类,几乎包罗万象。
在这里插入图片描述
今天我们使用的是hutool-captcha(图形验证码)。

引入依赖

这里使用的是Maven,如果是其他的项目构建工具,请参考文档。
单独引入图形验证码的依赖模块

    <!-- 添加图形验证码依赖 -->
    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-captcha</artifactId>
      <version>5.8.6</version>
    </dependency>

当然,为了方便,也可以按照文档中的方法,引入所有模块。

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.16</version>
</dependency>

在这里插入图片描述

LineCaptcha:线段干扰的验证码

    @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        //调用Hutool的图形验证码
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38, 5, 5);
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }
  • LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38, 5, 5);
    定义图形验证码的长、宽、验证码字符数、干扰线宽度
  • LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38)
    定义图形验证码的长、宽

上面这两种写法都是可以的
在这里插入图片描述

CircleCaptcha:圆形干扰验证码

 @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        //调用Hutool的图形验证码
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38, 5, 20);
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }
  • CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38, 5, 20);
    定义图形验证码的长、宽、验证码字符数、干扰⭕个数
  • CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38);
    定义图形验证码的长、宽

圆形干扰验证码同样两种写法。
在这里插入图片描述

ShearCaptcha:扭曲干扰验证码

    @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        //调用Hutool的图形验证码
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38,5,5);
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }
  • ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38,5,5);
    定义图形验证码的长、宽、验证码字符数、干扰线宽度
  • ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38);
    定义图形验证码的长、宽

在这里插入图片描述

GifCaptcha:GIF验证码

 @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        //调用Hutool的图形验证码
        GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38,5);
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }
  • GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38,5);
    定义GIF验证码的长、宽、验证码字符数
  • GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38);
    定义GIF验证码的长、宽

大家可以去试试,这里截不出那种Gif的效果
在这里插入图片描述

在这里插入图片描述

自定义验证码

在这里插入图片描述

纯数字验证码

    @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        // 自定义纯数字的验证码(随机4位数字,可重复)
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);
        captcha.setGenerator(randomGenerator);
// 重新生成code
        captcha.createCode();
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }

在这里插入图片描述
当然除了LineCaptcha,CircleCaptcha,GifCaptcha,ShearCaptcha都是可以的

纯字母验证码

    @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        // 自定义纯数字的验证码(随机4位数字,可重复)
        RandomGenerator randomGenerator = new RandomGenerator("abcdefghijklmnopqrstuvwyzx", 4);
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100);
        captcha.setGenerator(randomGenerator);
// 重新生成code
        captcha.createCode();
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }

在这里插入图片描述

四则运算验证码

 @GetMapping("/checkCode1")
    public void checkCode(HttpServletResponse response) throws IOException {
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
        // 自定义验证码内容为四则运算方式
        captcha.setGenerator(new MathGenerator());
        // 重新生成code
        captcha.createCode();
        //指示浏览器不要缓存页面内容
        response.setHeader("Pragma","no-cache");
        //进一步指示浏览器不要缓存页面内容
        response.setHeader("Cache-Control","no-cache");
        //表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
        response.setDateHeader("Expires",0);
        //表示返回的内容为JPEG格式的图片
        response.setContentType("image/jpeg");

        //图片验证码写出
        captcha.write(response.getOutputStream());
        //关闭流
        response.getOutputStream().close();
    }

在这里插入图片描述

相关文章:

  • 自学Python创建强大AI:从入门到实现DeepSeek级别的AI
  • bootstrap介绍(前端框架)(提供超过40种可复用组件,从导航栏到轮播图,从卡片到弹窗)bootstrap框架
  • 1688商品数据实战:API搜索接口开发与供应链分析应用
  • Linux--进程创建
  • CTF类题目复现总结-[WUSTCTF2020]girlfriend 1
  • wpa_supplicant驱动初始化源码分析
  • Gin框架学习
  • 【sgFloatDialog】自定义组件:浮动弹窗,支持修改尺寸、拖拽位置、最大化、还原、最小化、复位
  • Vue3 在组件中判断事件是否注册
  • js原型链与自动装箱机制
  • 从OSI七层网络模型角度了解CAN通信协议
  • 关于金融开发领域的一些专业知识总结
  • jmeter接口测试[-面试篇-]
  • 【YOLOv8改进 - C2f融合】C2f融合SCConv :即插即用的空间和通道重建卷积
  • 我的uniapp自定义模板
  • 基于SpringBoot + Vue 的药店药品信息管理系统
  • Yolo v4 (Darknet) Mac M2 安装与运行
  • kmp算法的实现
  • 测试专项3:算法测试基础理论速查手册
  • Spring Boot 整合 Apache Flink 教程
  • 广药集团原董事长李楚源被“双开”:去年8月被查,曾多次发表争议言论
  • 高瓴、景林旗下公司美股持仓揭晓:双双增持中概股
  • 俄乌代表团抵达谈判会场
  • 侵害孩子者,必严惩不贷!3名性侵害未成年人罪犯今日执行死刑
  • 女子七年后才知银行卡被盗刷18万元,警方抓获其前男友
  • 鸿海下调全年营收展望:AI服务器业务强劲,预计今年营收增超50%