springboot+ajax+验证码

分手后的思念是犯贱 2023-06-29 06:00 85阅读 0赞

一.效果

!\[\](https://img-blog.csdnimg.cn/2020011102053397.png?x-oss-process=image/watermark,type\_ZmFuZ3poZW5naGVpdGk,shadow\_10,text\_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1NDUzMjY2,size\_16,color\_FFFFFF,t\_70

二.整体流程

在这里插入图片描述

三.详细代码

前端:

1.发起ajax请求获取验证码图片,拿到图片src后动态刷新.

  1. function getVerifyCode() {
  2. $.ajax({
  3. url: URL + '/api/admin/code/',
  4. type: 'GET',
  5. data: {
  6. width: 180, //验证码图片的高
  7. height: 50, //验证码图片的宽
  8. },
  9. xhrFields: {
  10. withCredentials: true //前后端分离项目为解决跨域的问题必须这样设置
  11. },
  12. success: function (result) {
  13. var image = result.data.img;
  14. recordId = result.data.recordId;
  15. if (image != null && recordId != null) {
  16. $("#verify-code").attr("src", URL + image + ".png"); //动态刷新验证码图片
  17. $.cookie('recordId', recordId, { expires: 7, path: '/'}); //将验证码唯一标识recordId保存在cookie
  18. }
  19. }
  20. });
  21. }

2.点击刷新按钮,再次获取验证码图片

  1. function paperEvent() {
  2. $("#refresh").click(function () {
  3. getVerifyCode();
  4. });
  5. }

后端:

1.生成验证码工具类:

  1. package com.selenium.sdjubbs.common.util;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics2D;
  5. import java.awt.image.BufferedImage;
  6. import java.io.File;
  7. import java.io.IOException;
  8. import java.util.Random;
  9. import javax.imageio.ImageIO;
  10. /** * 随机生成验证码 * * @author selenium * */
  11. public class VerifyCodeUtil {
  12. public static String drawVerifyCode(int width, int height,String savePath,String imageName) throws IOException {
  13. StringBuffer verifyCode = new StringBuffer();
  14. Random random = new Random();
  15. BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  16. Font font = new Font("微软雅黑", Font.BOLD, 40);
  17. int degree = random.nextInt() % 30; // 旋转角度小于30度
  18. int x = 10; // 旋转原点的 x 坐标
  19. int ROTATE_Y = 45;// 旋转原点的 y 坐标
  20. Graphics2D graphics = bufferedImage.createGraphics();
  21. graphics.setColor(Color.WHITE);// 设置画笔颜色,也是验证码的背景色
  22. graphics.fillRect(0, 0, width, height);
  23. graphics.setFont(font);
  24. // 绘制验证码
  25. for (int i = 0; i < 4; i++) {
  26. graphics.setColor(getRandomColor());
  27. // 正向旋转
  28. graphics.rotate(degree * Math.PI / 180, x, ROTATE_Y);
  29. String ch = getRandomChar();
  30. verifyCode.append(ch);
  31. graphics.drawString(ch, x, ROTATE_Y);
  32. // 反向旋转
  33. graphics.rotate(-degree * Math.PI / 180, x, ROTATE_Y);
  34. x += 48;
  35. }
  36. // 画干扰线
  37. for (int i = 0; i < 6; i++) {
  38. graphics.setColor(getRandomColor());
  39. graphics.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width),
  40. random.nextInt(height));
  41. }
  42. // 添加噪点
  43. for (int i = 0; i < 30; i++) {
  44. graphics.setColor(getRandomColor());
  45. int x1 = random.nextInt(width);
  46. int y1 = random.nextInt(height);
  47. graphics.fillRect(x1, y1, 2, 2);
  48. }
  49. File dir =new File(savePath);
  50. if(!dir.exists()) {
  51. dir.mkdirs();
  52. }
  53. ImageIO.write(bufferedImage, "png",new File(savePath+File.separator+imageName+".png"));
  54. return verifyCode.toString();
  55. }
  56. /** * 随机取色 */
  57. private static Color getRandomColor() {
  58. Random random = new Random();
  59. Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
  60. return color;
  61. }
  62. /** * 随机生成每个验证码 * * @return */
  63. private static String getRandomChar() {
  64. String baseString = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
  65. Random random = new Random();
  66. String ch = baseString.charAt(random.nextInt(baseString.length())) + "";
  67. return ch;
  68. }
  69. }

2.验证码后端业务逻辑处理

  1. @GetMapping(Api.VERIFY_CODE)
  2. public Result getVerifyCode(int width, int height, HttpServletRequest request) {
  3. //根据ip作为用户标识,进行md5加密后取前10位,加密是因为图片名会用到ip,不直接暴露路径
  4. String ip = MD5Util.md5(request.getRemoteAddr()).substring(0, 10);
  5. String imagePath = "/common/" + setting.getVerifyCodeSavePath().split("/common/")[1];
  6. //验证码的存储路径为 项目在系统中的绝对路径/相对于项目的存储路径/
  7. String savePath = System.getProperty("user.dir") + setting.getVerifyCodeSavePath();
  8. //验证码存储图片名:ip_时间戳
  9. String imageName = ip + "_" + System.currentTimeMillis();
  10. //1.如果此ip之前有产生验证码图片,先删除之前产生的验证码图片,防止用户不停点击刷新,不停创建验证码图片
  11. // 消耗内存.
  12. //2.每次产生的验证码图片名都应该不一样,不能直接覆盖,不然点击刷新后,后端图片发生了变化,但前端
  13. // 却还是显示的之前的验证码图片
  14. FileUtil.deleteFilesWithPrefix(savePath, ip);
  15. String verifyCode = "";
  16. String recordId = "";
  17. String verifyCodeKey = "";
  18. try {
  19. verifyCode = VerifyCodeUtil.drawVerifyCode(width, height, savePath, imageName);
  20. //验证码的唯一标识符recordId
  21. recordId = System.currentTimeMillis() + UUID.randomUUID().toString();
  22. //存入redis中的key
  23. verifyCodeKey = "verifycode:" + ip + ":" + recordId;
  24. //60秒后验证码失效
  25. redisService.set(verifyCodeKey, verifyCode, 60);
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. //将图片路径和唯一标识符recordId返回给前端
  30. return Result.success().add("img", imagePath + "/" + imageName).add("recordId", recordId);
  31. }

出现的一些问题:

1.Springboot项目中验证码图片生成后,直接访问不到图片.
图片存储的路径(C:\src\idea\SDJUBBS\src\main\resources\static\common\images\verifycode\xxx.png)
图片访问的路径(http://localhost:8080/common/images/verifycode/xxx.png)
原因是因为tomcat对于静态资源有保护的措施,需要我们通过程序,将访问路径映射到实际的路径

  1. package com.selenium.sdjubbs.common.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  6. @Configuration
  7. public class ResourceConfig extends WebMvcConfigurerAdapter {
  8. @Autowired
  9. private SdjubbsSetting setting;
  10. @Override
  11. public void addResourceHandlers(ResourceHandlerRegistry registry) {
  12. //前面是映射后的地址,后面是需要映射的地址
  13. //获取文件的真实路径
  14. String path = System.getProperty("user.dir") + setting.getBaseDirSavePath();
  15. System.out.println(path);
  16. registry.addResourceHandler("/common/**").
  17. addResourceLocations("file:" + path);
  18. super.addResourceHandlers(registry);
  19. }
  20. }

发表评论

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

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

相关阅读