springboot图片验证码功能模块怎么实现
springboot图片验证码功能模块怎么实现
本篇内容主要讲解“springboot图片验证码功能模块怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springboot图片验证码功能模块怎么实现”吧!
具体效果如下:
第一步:工具类
该工具类为生成验证码图片的核心,直接拷贝到项目即可,无需做修改;可个性化的参数全部对外提供的API,比如 字体大小
,背景颜色
,干扰线数量
,高宽
等都可以根据自己的需求设置对应参数;
代码几乎每一行都加了详细的注释;如果遇上特殊的个性化需求,调整一下这个工具类即可实现。
packagecom.feng.util;/***@returnnull*@authorLadidol*@description*@date2022/4/1122:15*/importjava.awt.*;importjava.awt.geom.AffineTransform;importjava.awt.image.BufferedImage;importjava.util.Random;/***图形验证码生成*/publicclassVerifyUtil{//默认验证码字符集privatestaticfinalchar[]chars={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};//默认字符数量privatefinalIntegerSIZE;//默认干扰线数量privatefinalintLINES;//默认宽度privatefinalintWIDTH;//默认高度privatefinalintHEIGHT;//默认字体大小privatefinalintFONT_SIZE;//默认字体倾斜privatefinalbooleanTILT;privatefinalColorBACKGROUND_COLOR;/***初始化基础参数**@parambuilder*/privateVerifyUtil(Builderbuilder){SIZE=builder.size;LINES=builder.lines;WIDTH=builder.width;HEIGHT=builder.height;FONT_SIZE=builder.fontSize;TILT=builder.tilt;BACKGROUND_COLOR=builder.backgroundColor;}/***实例化构造器对象**@return*/publicstaticBuildernewBuilder(){returnnewBuilder();}/***@return生成随机验证码及图片*Object[0]:验证码字符串;*Object[1]:验证码图片。*/publicObject[]createImage(){StringBuffersb=newStringBuffer();//创建空白图片BufferedImageimage=newBufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);//获取图片画笔Graphics2Dgraphic=image.createGraphics();//设置抗锯齿graphic.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//设置画笔颜色graphic.setColor(BACKGROUND_COLOR);//绘制矩形背景graphic.fillRect(0,0,WIDTH,HEIGHT);//画随机字符Randomran=newRandom();//graphic.setBackground(Color.WHITE);//计算每个字符占的宽度,这里预留一个字符的位置用于左右边距intcodeWidth=WIDTH/(SIZE+1);//字符所处的y轴的坐标inty=HEIGHT*3/4;for(inti=0;i 使用默认参数: //生成图片验证码Object[]verify=VerifyUtil.newBuilder().build().createImage(); 自定义参数生成: //这个根据自己的需要设置对应的参数来实现个性化//返回的数组第一个参数是生成的验证码,第二个参数是生成的图片Object[]objs=VerifyUtil.newBuilder().setWidth(120)//设置图片的宽度.setHeight(35)//设置图片的高度.setSize(6)//设置字符的个数.setLines(10)//设置干扰线的条数.setFontSize(25)//设置字体的大小.setTilt(true)//设置是否需要倾斜.setBackgroundColor(Color.WHITE)//设置验证码的背景颜色.build()//构建VerifyUtil项目.createImage();//生成图片 需要引入的maven依赖: 获取相关的验证码: service层: packagecom.feng.service;importorg.cuit.epoch.result.Result;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;/***@returnnull*@authorLadidol*@description*@date2022/4/1122:15*/publicinterfaceVerifyService{/***创建图片验证码*@paramresponse*@paramrequest*@throwsIOException*/voidcreateCode(HttpServletResponseresponse,HttpServletRequestrequest)throwsIOException;/***检查图片验证码*@param*@param*@throwsIOException*/Result serviceimpl层: packagecom.feng.service.impl;importcom.feng.service.VerifyService;importcom.feng.util.RedisServiceImpl;importcom.google.common.net.HttpHeaders;importcom.feng.util.VerifyUtil;importorg.springframework.http.ResponseCookie;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;importjavax.imageio.ImageIO;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.http.HttpSession;importjava.awt.image.BufferedImage;importjava.io.IOException;importjava.io.OutputStream;importjava.time.Duration;/***@returnnull*@authorLadidol*@description*@date2022/4/1122:15*/@ServicepublicclassVerifyServiceImplimplementsVerifyService{@ResourceRedisServiceImplredisUtil;/***生成图片验证码*@paramresponse*@paramrequest*@throwsIOException*/@OverridepublicvoidcreateCode(HttpServletResponseresponse,HttpServletRequestrequest)throwsIOException{//获取sessionHttpSessionsession=request.getSession();//获得sessionIdStringid=session.getId();System.out.println();ResponseCookiecookie=ResponseCookie.from("JSESSIONID",id).secure(true).domain("").path("/").maxAge(Duration.ofHours(1)).sameSite("None").build();//清除之前缓存的图片验证码if(!String.valueOf(request.getSession().getAttribute("SESSION_VERIFY_CODE_"+id)).isEmpty()){StringgetVerify=String.valueOf(request.getSession().getAttribute("SESSION_VERIFY_CODE_"+id));redisUtil.del(getVerify);System.out.println("清除成功");}//生成图片验证码,用的默认参数Object[]verify=VerifyUtil.newBuilder().build().createImage();//将验证码存入sessionsession.setAttribute("SESSION_VERIFY_CODE_"+id,verify[0]);//打印验证码System.out.println(verify[0]);//将验证码存入redisredisUtil.set((String)verify[0],id,5*60);//将图片传给浏览器BufferedImageimage=(BufferedImage)verify[1];response.setContentType("image/png");response.setHeader(HttpHeaders.SET_COOKIE,cookie.toString());OutputStreamops=response.getOutputStream();ImageIO.write(image,"png",ops);}@OverridepublicResult 这里面还会用到redis相关的工具类,我就不列出来了,想要的话可以看我以前的博客工具类戳这里 controller层: packagecom.feng.controller;importlombok.RequiredArgsConstructor;importcom.feng.annotation.LimitRequest;importcom.feng.service.VerifyService;importorg.springframework.web.bind.annotation.*;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;/***@returnnull*@authorLadidol*@description这里主要就是多种验证码和登录相关的东西*@date2022/4/1121:46*/@RestController@RequestMapping("/verify")@RequiredArgsConstructor//这是在lombok工具给的注入方式,真帅publicclassVerifyController{privatefinalVerifyServiceverifyService;/***获取图片验证码*/@LimitRequest(count=5)//这个注解就是表示,你在限制时间里(我们这里默认是六秒钟),只能请求五次@GetMapping("/getCode")publicvoidgetCode(HttpServletResponseresponse,HttpServletRequestrequest)throwsIOException{verifyService.createCode(response,request);}@LimitRequest(count=5)//这个注解就是表示,你在限制时间里(我们这里默认是六秒钟),只能请求五次@GetMapping("/checkCode")publicResult 这里为了不被一直无限制的访问该服务, 我们用了一个限制ip访问次数的注解@LimitRequest annotion包下的注解类: packagecom.feng.annotation;importjava.lang.annotation.*;/***@returnnull*@authorLadidol*@description限制ip访问次数注解*@date2022/4/1122:15*/@Documented@Target(ElementType.METHOD)//说明该注解只能放在方法上面@Retention(RetentionPolicy.RUNTIME)public@interfaceLimitRequest{longtime()default6000;//限制时间单位:毫秒intcount()default3;//允许请求的次数} aspect包下的切面类: packagecom.feng.aspect;importnet.jodah.expiringmap.ExpirationPolicy;importnet.jodah.expiringmap.ExpiringMap;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Pointcut;importcom.feng.annotation.LimitRequest;importorg.cuit.epoch.exception.AppException;importorg.springframework.stereotype.Component;importorg.springframework.web.context.request.RequestAttributes;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletRequest;importjava.util.concurrent.ConcurrentHashMap;importjava.util.concurrent.TimeUnit;/***@returnnull*@authorLadidol*@description*@date2022/4/1122:15*/@Aspect@ComponentpublicclassLimitRequestAspect{privatestaticConcurrentHashMap 为了捕获全局的异常抛出, 且符合restful规范我们加一个这个处理类: handle包下面的全局异常类: packageorg.cuit.epoch.handler;importlombok.extern.log4j.Log4j2;importorg.cuit.epoch.exception.AppException;importorg.cuit.epoch.result.R;importorg.cuit.epoch.result.Result;importorg.springframework.web.bind.annotation.ControllerAdvice;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.ResponseBody;@ControllerAdvice@Log4j2publicclassGlobalExceptionHandler{@ExceptionHandler(Exception.class)@ResponseBodypublicResulterror(Exceptione){log.error(e.getMessage());e.printStackTrace();returnR.fail(e.getMessage());}@ExceptionHandler(AppException.class)@ResponseBodypublicResulterror(AppExceptione){log.error(e.getMessage());e.printStackTrace();returnR.fail(e.getMessage());}} application.yaml文件: spring:cache:type:redisredis:#redis连接配置host:自己redis的ip地址port:redis端口password:密码jedis:pool:max-active:8max-wait:-1msmax-idle:500min-idle:0lettuce:shutdown-timeout:0ms 最终项目结构如下: 先得到一个验证码: 验证一下是否成功: 成功结果: 验证失败结果: 当请求在规定时间内的请求数超过规定的数量时或有报错: 到此,相信大家对“springboot图片验证码功能模块怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是恰卡编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!第二步:图片生成:
整合到springboot项目中:
这里有用到@RequiredArgsConstructor, 就是简单的注入而已, 如果想要详细了解戳这里
推荐阅读
-
vue动态添加删除输入框(springboot vue怎么让数据库显示出来)
springbootvue怎么让数据库显示出来?一般情况下是前端调阅后端接口,来获取到数据库的数据,后端哪里会把数据库的数据整理...
-
springboot实现基于aop的切面日志
本文实例为大家分享了springboot实现基于aop的切面日志的具体代码,供大家参考,具体内容如下通过aop的切面方式实现日志...
-
SpringBoot定时任务功能怎么实现
-
SpringBoot中的@Import注解怎么使用
-
SpringBoot整合Lombok及常见问题怎么解决
SpringBoot整合Lombok及常见问题怎么解决这篇文章主要...
-
Springboot+SpringSecurity怎么实现图片验证码登录
-
SpringBoot注解的知识点有哪些
SpringBoot注解的知识点有哪些这篇“SpringBoot注...
-
SpringBoot2.x中management.security.enabled=false无效怎么解决
SpringBoot2.x中management.security.enabled=false无效怎么解决...
-
springboot怎么禁用某项健康检查
springboot怎么禁用某项健康检查今天小编给大家分享一下sp...
-
SpringBoot2怎么自定义端点
SpringBoot2怎么自定义端点这篇文章主要介绍“Spring...