SpringBoot+原生awt,实现花花绿绿的图形验证码

这篇具有很好参考价值的文章主要介绍了SpringBoot+原生awt,实现花花绿绿的图形验证码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

图形验证码是用于验证用户身份的一种方式,通常在网站注册、登录或进行某些敏感操作时会使用。它通过展示一个包含随机字符或数字的图形,要求用户输入相应的字符或数字来证明其为真人而非机器人。图形验证码能有效地防止机器人攻击和恶意注册行为,提高网站的安全性。

本文将基于 SpringBoot 和原生的 Java awt 包,完成图形验证码的实现,源码在 项目仓库 中,需要者可自助参考。

一、导入依赖

在实现图形验证码之前,首先要导入依赖,比如 SpringBoot 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

awt 包属于 Java 原生包,无需导入三方 maven 依赖,只需引入 JDK 即可。

二、编写工具类

接下来,就开始开发验证码的工具类,包括验证码配置、生成随机数、生成随机颜色、编写创建图片方法、编写构建函数,下面将逐一介绍。

2.1 验证码配置

首先是验证码的配置,创建 CreateVerifyCode 类,创建相应字段,包括字符个数、图片高度、图片宽度、干扰个数等参数,定义如下。

@ApiModelProperty(value = "验证码字符个数")
private int charactersNumber = 4;

@ApiModelProperty(value = "图片高度")
private int imagePeripheralHeight = 40;

@ApiModelProperty(value = "图片宽度")
private int imagePeripheralWidth = 160;

@ApiModelProperty(value = "干扰线数")
private int lineCount = 20;

2.2 生成随机数

新建一个方法 randomStr,用于实现生成随机数的功能,代码如下。

@ApiOperation(value = "随机生成验证码")
public String randomStr(int size) {
    String str1 = "0123456789";
    String str2 = "";
    for (int i = 0; i < size; i++) {
        double randomIndex = Math.random();
        double randomNumber = randomIndex * (str1.length() - 1);
        str2 += str1.charAt((int) randomNumber);
    }
    return str2;
}

2.3 生成随机颜色

新建一个方法 getRandColor,用于实现生成随机颜色的功能,代码如下。

@ApiOperation(value = "随机生成验证码颜色")
private Color getRandColor(int color1, int color2) {
    color1 = color1 > 255 ? 255 : color1;
    color2 = color2 > 255 ? 255 : color2;
    return new Color(color1 + random.nextInt(color2 - color1), color1 + random.nextInt(color2 - color1), color1 + random.nextInt(color2 - color1));
}

2.4 编写创建图片方法

有了验证码配置之后,新建一个方法 creatImage,用于实现图形验证码图片创建的逻辑,代码如下。

@ApiOperation(value = "图片生成工具类")
private void creatImage(String code) {
    if(ZwzNullUtils.isNull(code)){
        throw new ZwzException("图形验证码过期了,再生成个新的哦!");
    }
    this.code = code;
    buffImg = new BufferedImage(imagePeripheralWidth, imagePeripheralHeight, BufferedImage.TYPE_INT_RGB);
    Graphics g = buffImg.getGraphics();
    g.setColor(getRandColor(200, 250));
    g.fillRect(0, 0, imagePeripheralWidth, imagePeripheralHeight);
    Font font = new Font("Fixedsys", Font.BOLD, imagePeripheralHeight - 5);
    g.setFont(font);
    float yawpRate = 0.01f;
    int area = (int) (yawpRate * imagePeripheralWidth * imagePeripheralHeight);
    for (int i = 0; i < area; i++) {
        buffImg.setRGB(random.nextInt(imagePeripheralWidth), random.nextInt(imagePeripheralHeight), random.nextInt(255));
    }
    for (int i = 0; i < lineCount; i++) {
        int xs = random.nextInt(imagePeripheralWidth);
        int ys = random.nextInt(imagePeripheralHeight);
        int xe = xs + random.nextInt(imagePeripheralWidth);
        int ye = ys + random.nextInt(imagePeripheralHeight);
        g.setColor(getRandColor(2, 254));
        g.drawLine(xs, ys, xe, ye);
    }
    for (int i = 0; i < code.length(); i++) {
        String strRand = code.substring(i, i + 1);
        g.setColor(getRandColor(2, 254));
        g.drawString(strRand, i * (imagePeripheralWidth / charactersNumber) + 3, imagePeripheralHeight - 8);
    }
}

2.5 编写构建函数

为了用尽可能精简的代码实现图形验证码,构造函数是比不可少的,开发者可以在构建对象时直接传入参数,实现图形验证码的设计,代码如下。

public CreateVerifyCode(int imageWidth, int imageHeight, int codeCount, int lineCount, String code) {
    this.imagePeripheralWidth = imageWidth;
    this.imagePeripheralHeight = imageHeight;
    this.charactersNumber = codeCount;
    this.lineCount = lineCount;
    creatImage(code);
}

三、编写接口

工具类编写完成后,就开始设计 API 接口了,可以分为验证码初始化和图片返回。

3.1 验证码初始化

首先定义一个 init 接口,用户请求该接口时,系统利用 Java 的 UUID,生成一个随机字符串,并随机生成一个四位数字,放入缓存,返回该随机字符串,代码如下。

@RequestMapping(value = "/init", method = RequestMethod.GET)
@ApiOperation(value = "初始化验证码")
public Result<Object> init() {
    String codeId = UUID.randomUUID().toString().replace("-","");
    redisTemplate.opsForValue().set(codeId, new CreateVerifyCode().randomStr(4),2L, TimeUnit.MINUTES);
    return ResultUtil.data(codeId);
}

接口测试结果如下,接口返回了一个随机字符串bdb3cc192cf147eda20afa5e5d22bd8c

SpringBoot+原生awt,实现花花绿绿的图形验证码

3.2 图片返回

前端收到随机字符串 bdb3cc192cf147eda20afa5e5d22bd8c 后,再次请求,拿走验证码图片,核心代码如下。

@RequestMapping(value = "/draw/{captchaId}", method = RequestMethod.GET)
@ApiOperation(value = "根据验证码ID获取图片")
public void draw(@PathVariable("captchaId") String captchaId, HttpServletResponse response) throws IOException {
    String codeStr = redisTemplate.opsForValue().get(captchaId);
    CreateVerifyCode createVerifyCode = new CreateVerifyCode(116,36,4,10, codeStr);
    response.setContentType("image/png");
    createVerifyCode.write(response.getOutputStream());
}

首先根据随机字符串,在 redis 中拿到验证码的值,在调用验证码工具类生成图片,返回前端。

SpringBoot+原生awt,实现花花绿绿的图形验证码

SpringBoot+原生awt,实现花花绿绿的图形验证码

SpringBoot+原生awt,实现花花绿绿的图形验证码

3.3 验证码过滤

系统集成了 Spring Security,需要引入并重写 WebSecurityConfig 类,重写 securityFilterChain 方法。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http.authorizeHttpRequests().requestMatchers("/zwz/dictData/getByType/**","/zwz/file/view/**","/zwz/user/regist","/zwz/common/**","/*/*.js","/*/*.css","/*/*.png","/*/*.ico", "/swagger-ui.html").permitAll()
            .and().formLogin().loginPage("/zwz/common/needLogin").loginProcessingUrl("/zwz/login").permitAll()
            .successHandler(authenticationSuccessHandler).failureHandler(authenticationFailHandler).and()
            .headers().frameOptions().disable().and()
            .logout()
            .permitAll()
            .and()
            .authorizeHttpRequests()
            .anyRequest()
            .authenticated()
            .and()
            .cors().and()
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .exceptionHandling().accessDeniedHandler(zwzAccessDeniedHandler)
            .and()
            .authenticationProvider(authenticationProvider())
            .addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(imageValidateFilter, UsernamePasswordAuthenticationFilter.class);
    return http.build();
}

对于通过验证码的请求,给与放行,核心代码如下:

@Override
@ApiOperation(value = "验证码过滤")
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    Boolean filterFlag = false;
    for(String requestURI : captchaProperties.getVerification()){
        if(pathMatcher.match(requestURI, request.getRequestURI())){
            filterFlag = true;
            break;
        }
    }
    if(!filterFlag) {
        filterChain.doFilter(request, response);
        return;
    }
    String verificationCodeId = request.getParameter("captchaId");
    String userInputCode = request.getParameter("code");
    if(ZwzNullUtils.isNull(userInputCode) || ZwzNullUtils.isNull(verificationCodeId)){
        ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_CODE_FAIL_CODE,"验证码为空"));
        return;
    }
    String codeAnsInRedis = redisTemplate.opsForValue().get(verificationCodeId);
    if(ZwzNullUtils.isNull(codeAnsInRedis)){
        ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_CODE_FAIL_CODE,"已过期的验证码,需要重新填写"));
        return;
    }
    if(!Objects.equals(codeAnsInRedis.toLowerCase(),userInputCode.toLowerCase())) {
        ResponseUtil.out(response, ResponseUtil.resultMap(RESPONSE_FAIL_FLAG,RESPONSE_CODE_FAIL_CODE,"验证码不正确"));
        return;
    }
    redisTemplate.delete(verificationCodeId);
    filterChain.doFilter(request, response);
}

最终,基于 SpringBoot+原生 awt,实现花花绿绿的图形验证码。文章来源地址https://www.toymoban.com/news/detail-472057.html

到了这里,关于SpringBoot+原生awt,实现花花绿绿的图形验证码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前后端分离java开发图形验证码+谷歌开源Kaptcha使用(Springboot+redis实现图形验证码校验)

    注册 - 登录 - 修改密码 一般需要发送验证码,但是容易被攻击恶意调用。 手机短信轰炸机是批量、循环给手机无限发送各种网站的注册验证码短信的方法。 短信一条5分钱,如果被大盗刷大家自己计算邮箱通知不用钱,但被大盗刷,带宽、连接等都被占用,导致无法正常使用

    2024年01月19日
    浏览(57)
  • Java实现的五子棋游戏 ~java.awt&java.swing

    作业要求: (1)课题代号: 2 (2)课题名称: 2D 游戏设计 (3)课题要求:设计一种二维游戏(如数独,扫雷,飞机大战,贪食蛇,五子棋等),完成界面设计和必要的游戏功能 以下主要实现的功能有: 一、下棋功能,在棋盘的交点处落子。 二、简单人机对战功能。 1.实现

    2024年02月09日
    浏览(43)
  • unity 3d 场景变白了,模型发白,白花花一片,场景曝光了

    前面做了unity的三维场景,最近切换了unity for Intel和apple silicon的不同版本,发现我的场景变成了白花花的一片,超级曝光,运行程序也是一片的白,我的天呀。。。。 背景: 1,,unity 2021.3.5 for mac m1(apple silicon)非Intel 2,烘焙了灯光贴图。 疑似问题: 1,场景灯光;2,场景显示

    2024年02月11日
    浏览(34)
  • 【云原生】k8s图形化管理工具之rancher

    rancher是一个开源的企业级多集群的k8s管理平台。 rancher和k8s区别: 都是为了容器的调度和编排系统,但是rancher不仅能够调度,还能管理k8s集群,自带监控(普罗米修斯),大公司都是图形化。 rancher自带监控(普罗米修斯) master01 192.168.10.10 node01 192.168.10.20 node02 192.168.10.30 node04

    2024年01月25日
    浏览(48)
  • 【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合!

    🎉🎉 欢迎光临,终于等到你啦 🎉🎉 🏅我是 苏泽 ,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏 《Spring 狂野之旅:从入门到入魔》 🚀 本专栏带你从Spring入门到入魔   这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suzee.blog.

    2024年03月10日
    浏览(53)
  • 【K8S 云原生】K8S的图形化工具——Rancher

    目录 一、rancher概述 1、rancher概念 2、rancher和K8S的区别: 二、实验 1、安装部署 2、给集群添加监控: 3、创建命名空间: 4、创建deployment: 5、创建service: 6、创建ingress: 7、创建hpa 8、创建PVC 1、rancher概念 rancher实用一个开源的企业级多集群的K8S管理平台 2、rancher和K8S的区别

    2024年01月25日
    浏览(42)
  • 【WSL2】【图形界面】【CUDA驱动】WSL2 Ubuntu+gnome原生图形界面及WSL2显卡CUDA驱动的安装

      没有图形化界面的Ubuntu实在是看着不爽,虽然已经习惯用命令。为了更加方便使用WSL2子系统,还是配置了gnome原生桌面(虽然不是很轻量级,但是舒服啊!),然后因为有深度学习需求,有NVIDIA的显卡顺带配置了一下显卡驱动。   下面看看如何配置WSL2图形界面和显卡

    2024年02月10日
    浏览(61)
  • ImageIO的应用 (AWT和Swing初接触)

    在讲imageio之前,我们先来复习一下IO流的使用。 这里我建立一个Java类,用来实现读取文档中的内容,并且能够识别换行,话不多说,上代码: 代码是不是简洁易懂?有手就行。 注意一下,这里的文档需要建立在 F:Java_PrjJava_Project 包下 这里贴张图,展示一下文档内容 然后

    2024年02月08日
    浏览(70)
  • java.awt.FontFormatException: java.nio.BufferUnderflowException

    使用如上语句创建字体时出现问题。 java.awt.FontFormatException: java.nio.BufferUnderflowException 异常表明在处理字体数据时出现了缓冲区下溢(Buffer Underflow)的情况。这通常发生在尝试读取字体数据时,缓冲区的容量比所需数据少,导致无法从缓冲区中读取足够的字节。可能问题如下

    2024年04月09日
    浏览(31)
  • 【了解Java GUI编程】AWT和Swing的基本用法

    GUI :Graphical User Interface, 图形用户界面,指在 计算机 出现后,在屏幕上使用 图形界面 来帮助 用户(User) 与机器(Machine)打交道用的 界面接口(Interface)。 简单地理解,就是电脑打开的各个界面及弹窗,用户可进行鼠标、键盘等操作。 目录 一、AWT 1.1 组件和容器 1.1.1 AWT常用组

    2024年02月09日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包