Java实现随机验证码和验证码图片渲染功能

﹏ヽ暗。殇╰゛Y 2023-01-20 14:53 406阅读 0赞

0.注意事项:

  1. 图片格式(宽、高)、干扰线及数量在工具类的成员变量配置
  2. 验证码验证。验证码生成后是存储在session中的,使用相同的属性名(类似key)即可取出,然后进行比对

1. 验证码生成工具类

  1. package com.jbp.util;
  2. import java.awt.*;
  3. import java.awt.image.BufferedImage;
  4. import java.util.Random;
  5. /** * @ClassName: OptimizeVerificationCodeUtil * @description: 验证码生产工具类优化版 * @author: JiangBeiPing * @create: 2021-05-12 10:12 * @Version: 1.0 **/
  6. public class OptimizeVerificationCodeUtil {
  7. /** * 验证码图片 */
  8. private BufferedImage image;
  9. /** * 验证码 */
  10. private String verificationCode;
  11. /** * 生成的验证码的类型(目前的业务类型只需要数字类型) */
  12. private static char[] codeSequence = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  13. /** * 存入Session的验证码的属性名称 */
  14. public static final String SESSION_VERIFICATION_CODE = "validateCode";
  15. /** * 设置验证码图片的宽度 */
  16. private static final int WIDTH = 600;
  17. /** * 设置验证码图片的高度 */
  18. private static final int HEIGHT = 200;
  19. /** * 设置验证码字符的个数 */
  20. private static final int CODE_COUNT = 4;
  21. /** * 设置验证码图片干扰线的数量 */
  22. private static final int INTERFERING_LINE_COUNT = 160;
  23. private OptimizeVerificationCodeUtil() {
  24. // 初始化过程中生产并渲染验证码图片
  25. init();
  26. }
  27. /** * 对外提供的本工具类的实例 * * @return 工具类的实例 */
  28. public static OptimizeVerificationCodeUtil instance() {
  29. return new OptimizeVerificationCodeUtil();
  30. }
  31. /** * 获取验证码图片 * * @return 验证码图片 */
  32. public BufferedImage getImage() {
  33. return this.image;
  34. }
  35. /** * 获取验证码 * * @return 验证码 */
  36. public String getVerificationCode() {
  37. return this.verificationCode;
  38. }
  39. private void init() {
  40. // 在内存中创建验证码图片
  41. BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
  42. // 获取图形上下文
  43. Graphics2D graphics = bufferedImage.createGraphics();
  44. try {
  45. // 随机数生成器类
  46. Random random = new Random();
  47. // 图像背景设置为白色
  48. graphics.setColor(Color.white);
  49. graphics.fillRect(0, 0, WIDTH, HEIGHT);
  50. // 创建字体,字体的大小应该根据图片的高度来定
  51. Font font = new Font("Fixedsys", Font.PLAIN, HEIGHT - 2);
  52. // 设置字体
  53. graphics.setFont(font);
  54. // 画边框
  55. graphics.setColor(Color.BLACK);
  56. graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
  57. // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到
  58. for (int i = 0; i < INTERFERING_LINE_COUNT; i++) {
  59. // 每条干扰线都设置为随机颜色
  60. graphics.setColor(getRandomColor());
  61. int x2 = random.nextInt(WIDTH);
  62. int y2 = random.nextInt(HEIGHT);
  63. int x1 = random.nextInt(WIDTH);
  64. int y1 = random.nextInt(HEIGHT);
  65. graphics.drawLine(x2, y2, x2 + x1, y2 + y1);
  66. }
  67. // randomCode用于保存随机产生的验证码,以便用户登录后进行验证
  68. StringBuilder randomCode = new StringBuilder();
  69. int x = WIDTH / (CODE_COUNT + 1);
  70. int codeY = HEIGHT - 4;
  71. // 随机产生 codeCount 数字的验证码
  72. for (int i = 0; i < CODE_COUNT; i++) {
  73. // 获取随机产生的验证码数字
  74. String strRand = String.valueOf(codeSequence[random.nextInt(10)]);
  75. // 用随机产生的颜色将验证码绘制到图像中
  76. graphics.setColor(getRandomColor());
  77. graphics.drawString(strRand, (i + 1) * x, codeY);
  78. // 将产生的四个随机数组合在一起
  79. randomCode.append(strRand);
  80. }
  81. // 赋值验证码
  82. this.verificationCode = String.valueOf(randomCode);
  83. // 赋值图像
  84. this.image = bufferedImage;
  85. } finally {
  86. // 不关闭的话有OOM风险
  87. graphics.dispose();
  88. }
  89. }
  90. /** * 生成随机颜色 * @return 随机颜色 */
  91. private static Color getRandomColor() {
  92. Random random = new Random();
  93. return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
  94. }
  95. }

2. Controller层

  1. package com.jbp.controller;
  2. import com.jbp.util.OptimizeVerificationCodeUtil;
  3. import com.jbp.util.VerificationCodeUtil;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.apache.commons.lang.StringUtils;
  6. import org.springframework.web.bind.annotation.PostMapping;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RequestMethod;
  9. import org.springframework.web.bind.annotation.RestController;
  10. import javax.imageio.ImageIO;
  11. import javax.servlet.ServletOutputStream;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import javax.servlet.http.HttpSession;
  15. import java.awt.image.BufferedImage;
  16. import java.io.IOException;
  17. import java.util.Map;
  18. /** * @ClassName: VerificationCodeController * @description: 验证码Controller * @author: JiangBeiPing * @create: 2021-05-11 11:28 * @Version: 1.0 **/
  19. @RequestMapping("/verification")
  20. @RestController
  21. @Slf4j
  22. public class VerificationCodeController {
  23. @RequestMapping(value = "/getSecurityCode", produces = { "application/json;charset=UTF-8"},method = RequestMethod.GET)
  24. public void getSecurityCode(HttpServletResponse response, HttpServletRequest request){
  25. // 通知浏览器不要缓存
  26. response.setHeader("Expires","-1");
  27. response.setHeader("Cache-Control", "no-cache");
  28. response.setHeader("Pragma", "-1");
  29. // 将验证码输入到session中,用来验证
  30. OptimizeVerificationCodeUtil optimizeVerificationCodeUtil = OptimizeVerificationCodeUtil.instance();
  31. String verificationCode = optimizeVerificationCodeUtil.getVerificationCode();
  32. request.getSession().setAttribute(OptimizeVerificationCodeUtil.SESSION_VERIFICATION_CODE,verificationCode);
  33. try {
  34. ImageIO.write(optimizeVerificationCodeUtil.getImage(), "jpg", response.getOutputStream());
  35. } catch (IOException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }

3. 效果测试

ps:无视水印,问就是在划水
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,406人围观)

还没有评论,来说两句吧...

相关阅读