java实现随机验证码图片生成

作者:夕阳西下,断肠人在天涯 时间:2022-12-08 02:27:00 

本文实例为大家分享了java生成随机验证码图片的具体代码,供大家参考,具体内容如下

1.controller


/**
    * 获取随机数验证码图片
    *
    * @param request  HttpServletRequest
    * @param response HttpServletResponse
    */
   @GetMapping(value = "/getRandomCode" ,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
   public void getRandomCode(HttpServletRequest request, HttpServletResponse response) {
       baseService.getRandomCode(request, response);
}

2.service


void getRandomCode(HttpServletRequest request, HttpServletResponse response);

3.serviceImpl


@Autowired

private RedisTemplate redisTemplate;

@Autowired
   private CodeImageUtils codeImageUtils;
   /**
    *  获取随机数验证码图片
    */
   @Override
   public void getRandomCode(HttpServletRequest request, HttpServletResponse response) {
       try {
           // 设置输出类型为图片
           response.setContentType("image/jpeg");

// 生成随机码
           String verificationCode = codeImageUtils.getRandomCode();

// 背景颜色与字符颜色
           Color color = codeImageUtils.getRandomColor();
           Color reverseColor = codeImageUtils.getReverseColor(color);

//创建一张彩色的图片
           BufferedImage bi = new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);
           Graphics2D graphics = bi.createGraphics();
           //设置字体
           graphics.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
           graphics.setColor(color);
           //绘制背景
           graphics.fillRect(0, 0, 100, 30);
           graphics.setColor(reverseColor);
           //绘制字符
           graphics.drawString(verificationCode, 18, 20);

//绘制最多50个随机噪点//绘制最多50个随机噪点
           Random random = new Random();
           int n = random.nextInt(50);
           for (int i = 0; i < n; i++) {
               graphics.drawRect(100, 30, 1, 1);
           }

// 放到redis中 sessionId:code,过期时间60s
           redisTemplate.opsForValue().set(request.getSession().getId(),verificationCode,60, TimeUnit.SECONDS);

//输出到客户端
           ServletOutputStream sos = response.getOutputStream();
           JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(sos);
           encoder.encode(bi);
           sos.flush();
       }catch (Exception ex){
           log.error("生成验证码失败!",ex);
       }
   }

4.CodeImageUtils


@Component
public class CodeImageUtils {

@Autowired
   RedisTemplate redisTemplate;

/**
    * 生成4位随机的验证码字符串
    *
    * @return
    */
   public  String getRandomCode() {
       // 通过random生成4位随机数字码
       Random random = new Random();
       StringBuilder rs = new StringBuilder();
       for (int i = 0; i < 4; i++) {
           rs.append(random.nextInt(10));
       }
       return rs.toString();
   }

/**
    * 生成随机的颜色
    *
    * @return
    */
   public  Color getRandomColor() {
       Random random = new Random();
       return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
   }

/**
    * 获取某颜色的反色
    * @param color
    * @return
    */
   public  Color getReverseColor(Color color) {
       return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue());
   }

/**
    * 校验
    * @param code
    * @return
    */
   public boolean valid(HttpServletRequest request,String code){
       // 获取缓存的code
      Object cacheCode =  redisTemplate.opsForValue().get(request.getSession().getId());
      if(cacheCode ==null){
          return false;
      }
      return code.equals(cacheCode);
   }
}

5.请求该接口

java实现随机验证码图片生成

6.ImageIO

JPEGCodec这个在高版本的jdk中过期了,替换为ImageIO


//输出到客户端
           ServletOutputStream sos = response.getOutputStream();
           /*JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(sos);
           encoder.encode(bi);*/
           ImageIO.write(bi, "PNG", sos);
           sos.flush();

7.sessionId不一致

以上代码在单节点部署情况下暂时没发现什么问题,但是在多节点部署时会出现sessionId不一致的问题,(别问我怎么知道的…踩坑使我进步)。

解决方案为使用@EnableRedisHttpSession注解来开启session共享。

新增依赖


<dependency>
           <groupId>org.springframework.session</groupId>
           <artifactId>spring-session-data-redis</artifactId>
           <version>2.1.12.RELEASE</version>
</dependency>

新增配置


@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400)

来源:https://blog.csdn.net/fh_luchenxi/article/details/121086284

标签:java,验证码
0
投稿

猜你喜欢

  • MyBatis找不到mapper文件的实现

    2023-12-15 09:22:11
  • java模拟斗地主发牌功能

    2023-06-26 08:01:34
  • Scala方法与函数使用和定义详解

    2021-10-05 06:34:12
  • Java实现上传文件图片到指定服务器目录

    2023-06-28 00:23:32
  • c# 读取XML文件的示例

    2023-11-04 00:51:17
  • C#类的创建与初始化实例解析

    2023-08-05 17:55:31
  • 生成8位随机不重复的数字编号的方法

    2023-11-26 07:00:29
  • Java 获取当前系统时间的三种方法

    2023-11-21 12:51:51
  • 新的Java访问mysql数据库工具类的操作代码

    2023-04-05 16:54:58
  • Springboot与vue实现数据导出方法具体介绍

    2023-11-06 21:00:34
  • c# 通过wbemtest和WMI Code Cretor更加高效的访问WMI

    2022-11-17 16:30:16
  • 为何Java8需要引入新的日期与时间库

    2023-12-16 06:02:23
  • C#中XmlTextWriter读写xml文件详细介绍

    2022-01-26 05:13:48
  • C# Console利用mspaint打开图像并保存的方法

    2023-07-05 16:15:43
  • 利用Thumbnailator轻松实现图片缩放、旋转与加水印

    2022-03-26 18:44:04
  • Java案例使用比较排序器comparator实现成绩排序

    2023-10-16 01:37:24
  • 基于java 线程的几种状态(详解)

    2022-08-31 19:51:47
  • springboot使用之多个filter的执行顺序以及配置方式

    2023-11-09 09:30:59
  • Java中TypeReference用法详情说明

    2023-11-24 19:05:05
  • springboot整合mybatis plus与druid详情

    2022-07-31 14:22:14
  • asp之家 软件编程 m.aspxhome.com