• java生成验证码返回前端图片,后端通过redis存储和校验


    目录

    1.导入maven

    2.编写config类

    3.编写controller

    4.验证


    1.导入maven

    1. com.github.penggle
    2. kaptcha
    3. 2.3.2

    2.编写config类

    CaptchaConfig  

    这里使用的是:1*2=2 这样的验证形式,因此我配了一个bean名为captchaProducerMath的验证码配置。

    光配置不行,我通过属性properties.setProperty设置了生成格式,也就是验证码文本器。

    验证码文本器通过重写getText方法定义生成的格式。格式为10以内的+-*/

    注意:验证码文本器改成自己的路径

    1. package com.zsp.quartz.config;
    2. import com.google.code.kaptcha.impl.DefaultKaptcha;
    3. import com.google.code.kaptcha.util.Config;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.Configuration;
    6. import java.util.Properties;
    7. import static com.google.code.kaptcha.Constants.*;
    8. /**
    9. * 验证码配置
    10. */
    11. @Configuration
    12. public class CaptchaConfig
    13. {
    14. @Bean(name = "captchaProducer")
    15. public DefaultKaptcha getKaptchaBean()
    16. {
    17. DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
    18. Properties properties = new Properties();
    19. // 是否有边框 默认为true 我们可以自己设置yes,no
    20. properties.setProperty(KAPTCHA_BORDER, "yes");
    21. // 验证码文本字符颜色 默认为Color.BLACK
    22. properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
    23. // 验证码图片宽度 默认为200
    24. properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
    25. // 验证码图片高度 默认为50
    26. properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
    27. // 验证码文本字符大小 默认为40
    28. properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
    29. // KAPTCHA_SESSION_KEY
    30. properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
    31. // 验证码文本字符长度 默认为5
    32. properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
    33. // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
    34. properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
    35. // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
    36. properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
    37. Config config = new Config(properties);
    38. defaultKaptcha.setConfig(config);
    39. return defaultKaptcha;
    40. }
    41. @Bean(name = "captchaProducerMath")
    42. public DefaultKaptcha getKaptchaBeanMath()
    43. {
    44. DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
    45. Properties properties = new Properties();
    46. // 是否有边框 默认为true 我们可以自己设置yes,no
    47. properties.setProperty(KAPTCHA_BORDER, "yes");
    48. // 边框颜色 默认为Color.BLACK
    49. properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
    50. // 验证码文本字符颜色 默认为Color.BLACK
    51. properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
    52. // 验证码图片宽度 默认为200
    53. properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
    54. // 验证码图片高度 默认为50
    55. properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
    56. // 验证码文本字符大小 默认为40
    57. properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
    58. // KAPTCHA_SESSION_KEY
    59. properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
    60. // 验证码文本生成器
    61. properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.zsp.quartz.config.KaptchaTextCreator");
    62. // 验证码文本字符间距 默认为2
    63. properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
    64. // 验证码文本字符长度 默认为5
    65. properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
    66. // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
    67. properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
    68. // 验证码噪点颜色 默认为Color.BLACK
    69. properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
    70. // 干扰实现类
    71. properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
    72. // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
    73. properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
    74. Config config = new Config(properties);
    75. defaultKaptcha.setConfig(config);
    76. return defaultKaptcha;
    77. }
    78. }
    KaptchaTextCreator验证码文本生成器

    继承DefaultTextCreator,覆盖原有的getText()方法

    1. package com.zsp.quartz.config;
    2. import com.google.code.kaptcha.text.impl.DefaultTextCreator;
    3. import java.util.Random;
    4. /**
    5. * 验证码文本生成器
    6. */
    7. public class KaptchaTextCreator extends DefaultTextCreator
    8. {
    9. private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
    10. @Override
    11. public String getText()
    12. {
    13. Integer result = 0;
    14. Random random = new Random();
    15. int x = random.nextInt(10);
    16. int y = random.nextInt(10);
    17. StringBuilder suChinese = new StringBuilder();
    18. int randomoperands = (int) Math.round(Math.random() * 2);
    19. if (randomoperands == 0)
    20. {
    21. result = x * y;
    22. suChinese.append(CNUMBERS[x]);
    23. suChinese.append("*");
    24. suChinese.append(CNUMBERS[y]);
    25. }
    26. else if (randomoperands == 1)
    27. {
    28. if (!(x == 0) && y % x == 0)
    29. {
    30. result = y / x;
    31. suChinese.append(CNUMBERS[y]);
    32. suChinese.append("/");
    33. suChinese.append(CNUMBERS[x]);
    34. }
    35. else
    36. {
    37. result = x + y;
    38. suChinese.append(CNUMBERS[x]);
    39. suChinese.append("+");
    40. suChinese.append(CNUMBERS[y]);
    41. }
    42. }
    43. else if (randomoperands == 2)
    44. {
    45. if (x >= y)
    46. {
    47. result = x - y;
    48. suChinese.append(CNUMBERS[x]);
    49. suChinese.append("-");
    50. suChinese.append(CNUMBERS[y]);
    51. }
    52. else
    53. {
    54. result = y - x;
    55. suChinese.append(CNUMBERS[y]);
    56. suChinese.append("-");
    57. suChinese.append(CNUMBERS[x]);
    58. }
    59. }
    60. else
    61. {
    62. result = x + y;
    63. suChinese.append(CNUMBERS[x]);
    64. suChinese.append("+");
    65. suChinese.append(CNUMBERS[y]);
    66. }
    67. suChinese.append("=?@" + result);
    68. return suChinese.toString();
    69. }
    70. }

    3.编写controller

    1. package com.zsp.quartz.controller;
    2. import cn.hutool.core.codec.Base64;
    3. import com.google.code.kaptcha.Producer;
    4. import com.zsp.quartz.Exception.CustomException;
    5. import com.zsp.quartz.entity.dto.CaptchaDto;
    6. import com.zsp.quartz.result.Result;
    7. import com.zsp.quartz.service.Constants;
    8. import com.zsp.quartz.util.IdUtils;
    9. import org.springframework.data.redis.core.RedisTemplate;
    10. import org.springframework.data.redis.core.ValueOperations;
    11. import org.springframework.util.FastByteArrayOutputStream;
    12. import org.springframework.web.bind.annotation.*;
    13. import javax.annotation.Resource;
    14. import javax.imageio.ImageIO;
    15. import java.awt.image.BufferedImage;
    16. import java.io.IOException;
    17. @RestController
    18. @RequestMapping("/test")
    19. @CrossOrigin
    20. public class TestController {
    21. @Resource(name = "captchaProducerMath")
    22. private Producer captchaProducerMath;
    23. private RedisTemplate stringRedisTemplate;
    24. /**
    25. * 生成验证码
    26. */
    27. @GetMapping("/captchaImage")
    28. public Result getCode() throws IOException
    29. {
    30. // 保存验证码信息
    31. String uuid =UUID.randomUUID().toString();
    32. // 存入redis的key
    33. String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
    34. String capStr = null, code = null;
    35. BufferedImage image = null;
    36. // 生成验证码
    37. // 生成具体的验证码信息 诸如2/2=?@1
    38. String capText = captchaProducerMath.createText();
    39. // 以@进行分割获取问题
    40. capStr = capText.substring(0, capText.lastIndexOf("@"));
    41. //以@进行分割,获取最终的实际结果
    42. // 存入redis的值
    43. code = capText.substring(capText.lastIndexOf("@") + 1);
    44. image = captchaProducerMath.createImage(capStr);
    45. // 存入缓存 CAPTCHA_EXPIRATION验证码有效期
    46. stringRedisTemplate.opsForValue().set(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
    47. // 转换流base64信息写出
    48. FastByteArrayOutputStream os = new FastByteArrayOutputStream();
    49. try
    50. {
    51. ImageIO.write(image, "jpg", os);
    52. }
    53. catch (IOException e)
    54. {
    55. return Result.fail("生成失败",new CaptchaDto());
    56. }
    57. CaptchaDto captchaDto = new CaptchaDto();
    58. captchaDto.setUuid(uuid); // c8a94873-2c18-4199-871a-c6a6bd2b5241
    59. captchaDto.setImg(Base64.encode(os.toByteArray()));
    60. return Result.success("生成成功",captchaDto);
    61. }
    62. /**
    63. * 校验验证码
    64. * @param code 验证码
    65. * @param uuid 唯一标识
    66. * @return 结果
    67. */
    68. @PostMapping("validateCaptcha")
    69. public Result validateCaptcha(String code,String uuid){
    70. // redis的key 前端传来的
    71. String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
    72. ValueOperations valueOperations = stringRedisTemplate.opsForValue();
    73. String captcha = valueOperations.get(verifyKey);
    74. stringRedisTemplate.delete(verifyKey);
    75. if (captcha == null) {
    76. throw new CustomException("验证码已过期");
    77. }
    78. if (!code.equalsIgnoreCase(captcha)) {
    79. throw new CustomException("验证码不正确");
    80. }
    81. return Result.success("验证成功");
    82. }
    83. }
    1. /**
    2. * 验证码 redis key
    3. */
    4. public static final String CAPTCHA_CODE_KEY = "captcha_codes:";

    4.验证

    postman测试生成验证码图片

    base64图片要想在浏览器显示,需要前面加上    data:image/gif;base64,

    逗号不要忘了

    验证码校验,输入结果和uuid

  • 相关阅读:
    Python imgaug库的使用
    Vue学习:模板语法
    结合scss实现黑白主题切换
    【Android面试八股文】性能优化相关面试题: 什么是内存抖动?什么是内存泄漏?
    《C++标准库第2版》3.2 虽旧犹新的语言特性 笔记
    布尔盲注知识点
    【进阶篇】MySQL分库分表详解
    FlowJo 10.4.0(流式细胞分析器工具)
    CSDN编程竞赛-第六期(下)
    Springboot项目:连接mysql数据库,使用aop进行日志捕获
  • 原文地址:https://blog.csdn.net/m0_55627541/article/details/133698308