Spring Boot中验证码实现kaptcha
要生成验证码网上的方案比较多,基本是基于两大类:1为自定义生成,操作用Image类,2为kaptcha生成,有模糊算法。
当然也可以直接交由前端进行处理
1、基于kaptcha
首先不要怀疑的是报名是GitHub还是Google的,因为都是出自私人的产物,并且之前在Google Code进行托管,然后关闭了Google Code之后,有人就把其转入到GitHub中,并且不只一个人,所以才会造成市面上这么多不同的报名。
但总体功能基本不变。
下面POM先引入包:
<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha --> <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version> </dependency>
这个包也不要怀疑,在GitHub上的星星是最多的。
KaptchaConfig.java
import java.util.Properties; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; @Component public class KaptchaConfig { @Bean public DefaultKaptcha getDefaultKaptcha(){ com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha(); Properties properties = new Properties(); properties.setProperty("kaptcha.border", "yes"); properties.setProperty("kaptcha.border.color", "105,179,90"); properties.setProperty("kaptcha.textproducer.font.color", "blue"); properties.setProperty("kaptcha.image.width", "110"); properties.setProperty("kaptcha.image.height", "40"); properties.setProperty("kaptcha.textproducer.font.size", "30"); properties.setProperty("kaptcha.session.key", "code"); properties.setProperty("kaptcha.textproducer.char.length", "4"); properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑"); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } }
这个配置文件可以写成XML,然后通过在main方法使用@ImportResource进行导入XML配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha"> <property name="config"> <bean class="com.google.code.kaptcha.util.Config"> <constructor-arg type="java.util.Properties"> <props> <prop key = "kaptcha.border ">yes</prop> <prop key="kaptcha.border.color">105,179,90</prop> <prop key="kaptcha.textproducer.font.color">blue</prop> <prop key="kaptcha.image.width">100</prop> <prop key="kaptcha.image.height">50</prop> <prop key="kaptcha.textproducer.font.size">27</prop> <prop key="kaptcha.session.key">code</prop> <prop key="kaptcha.textproducer.char.length">4</prop> <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop> <prop key="kaptcha.textproducer.char.string">0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ</prop> <prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.WaterRipple</prop> <prop key="kaptcha.noise.color">black</prop> <prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.DefaultNoise</prop> <prop key="kaptcha.background.clear.from">185,56,213</prop> <prop key="kaptcha.background.clear.to">white</prop> <prop key="kaptcha.textproducer.char.space">3</prop> </props> </constructor-arg> </bean> </property> </bean> </beans>
@SpringBootApplication @ImportResource(locations={"classpath:mykaptcha.xml"}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
注意:以上的main方法是导入XML文件的写法,普通注解方式不需要这么写。普通即可。
Controller,生成验证码
@Autowired DefaultKaptcha defaultKaptcha;@RequestMapping("/defaultKaptcha") public void defaultKaptcha(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws Exception{ byte[] captchaChallengeAsJpeg = null; ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); try { //生产验证码字符串并保存到session中 String createText = defaultKaptcha.createText(); httpServletRequest.getSession().setAttribute("vrifyCode", createText); //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中 BufferedImage challenge = defaultKaptcha.createImage(createText); ImageIO.write(challenge, "jpg", jpegOutputStream); } catch (IllegalArgumentException e) { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); return; } //定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组 captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); httpServletResponse.setHeader("Cache-Control", "no-store"); httpServletResponse.setHeader("Pragma", "no-cache"); httpServletResponse.setDateHeader("Expires", 0); httpServletResponse.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream(); responseOutputStream.write(captchaChallengeAsJpeg); responseOutputStream.flush(); responseOutputStream.close(); }
验证方法
@RequestMapping("/imgvrifyControllerDefaultKaptcha") public ModelAndView imgvrifyControllerDefaultKaptcha(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse){ ModelAndView andView = new ModelAndView(); String captchaId = (String) httpServletRequest.getSession().getAttribute("vrifyCode"); String parameter = httpServletRequest.getParameter("vrifyCode"); System.out.println("Session vrifyCode "+captchaId+" form vrifyCode "+parameter); if (!captchaId.equals(parameter)) { andView.addObject("info", "错误的验证码"); andView.setViewName("index"); } else { andView.addObject("info", "登录成功"); andView.setViewName("succeed"); } return andView; }
配置项参考:
kaptcha.border 是否有边框 默认为true 我们可以自己设置yes,no kaptcha.border.color 边框颜色 默认为Color.BLACK kaptcha.border.thickness 边框粗细度 默认为1 kaptcha.producer.impl 验证码生成器 默认为DefaultKaptcha kaptcha.textproducer.impl 验证码文本生成器 默认为DefaultTextCreator kaptcha.textproducer.char.string 验证码文本字符内容范围 默认为abcde2345678gfynmnpwx kaptcha.textproducer.char.length 验证码文本字符长度 默认为5 kaptcha.textproducer.font.names 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) kaptcha.textproducer.font.size 验证码文本字符大小 默认为40 kaptcha.textproducer.font.color 验证码文本字符颜色 默认为Color.BLACK kaptcha.textproducer.char.space 验证码文本字符间距 默认为2 kaptcha.noise.impl 验证码噪点生成对象 默认为DefaultNoise kaptcha.noise.color 验证码噪点颜色 默认为Color.BLACK kaptcha.obscurificator.impl 验证码样式引擎 默认为WaterRipple kaptcha.word.impl 验证码文本字符渲染 默认为DefaultWordRenderer kaptcha.background.impl 验证码背景生成器 默认为DefaultBackground kaptcha.background.clear.from 验证码背景颜色渐进 默认为Color.LIGHT_GRAY kaptcha.background.clear.to 验证码背景颜色渐进 默认为Color.WHITE kaptcha.image.width 验证码图片宽度 默认为200 kaptcha.image.height 验证码图片高度 默认为50
2、自定义方案
验证码生成类
import java.awt.*; import java.awt.image.BufferedImage; import java.io.OutputStream;import java.util.HashMap; import java.util.Map;import java.util.Random;public class ImageCode {private static char mapTable[] = {'0', '1', '2', '3', '4', '5','6', '7', '8', '9', '0', '1','2', '3', '4', '5', '6', '7','8', '9'};public static Map<String, Object> getImageCode(int width, int height, OutputStream os) {Map<String,Object> returnMap = new HashMap<String, Object>();if (width <= 0) width = 60;if (height <= 0) height = 20;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取图形上下文Graphics g = image.getGraphics();//生成随机类Random random = new Random();// 设定背景色g.setColor(getRandColor(200, 250));g.fillRect(0, 0, width, height);//设定字体g.setFont(new Font("Times New Roman", Font.PLAIN, 18));// 随机产生168条干扰线,使图象中的认证码不易被其它程序探测到g.setColor(getRandColor(160, 200));for (int i = 0; i < 168; i++) {int x = random.nextInt(width);int y = random.nextInt(height);int xl = random.nextInt(12);int yl = random.nextInt(12);g.drawLine(x, y, x + xl, y + yl);}//取随机产生的码String strEnsure = "";//4代表4位验证码,如果要生成更多位的认证码,则加大数值for (int i = 0; i < 4; ++i) {strEnsure += mapTable[(int) (mapTable.length * Math.random())];// 将认证码显示到图象中g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));//直接生成String str = strEnsure.substring(i, i + 1);g.drawString(str, 13 * i + 6, 16);}// 释放图形上下文 g.dispose();returnMap.put("image",image);returnMap.put("strEnsure",strEnsure);return returnMap;}//给定范围获得随机颜色static Color getRandColor(int fc, int bc) {Random random = new Random();if (fc > 255) fc = 255;if (bc > 255) bc = 255;int r = fc + random.nextInt(bc - fc);int g = fc + random.nextInt(bc - fc);int b = fc + random.nextInt(bc - fc);return new Color(r, g, b);} }
获取验证码API
@RequestMapping(value = "/images/imagecode") public String imagecode(HttpServletRequest request, HttpServletResponse response) throws Exception {OutputStream os = response.getOutputStream();Map<String,Object> map = ImageCode.getImageCode(60, 20, os);String simpleCaptcha = "simpleCaptcha";request.getSession().setAttribute(simpleCaptcha, map.get("strEnsure").toString().toLowerCase());request.getSession().setAttribute("codeTime",new Date().getTime());try {ImageIO.write((BufferedImage) map.get("image"), "JPEG", os);} catch (IOException e) {return "";}return null; }
验证验证码API
@RequestMapping(value = "/checkcode") @ResponseBody public String checkcode(HttpServletRequest request, HttpSession session) throws Exception {String checkCode = request.getParameter("checkCode");Object cko = session.getAttribute("simpleCaptcha") ; //验证码对象if(cko == null){request.setAttribute("errorMsg", "验证码已失效,请重新输入!");return "验证码已失效,请重新输入!";}String captcha = cko.toString();Date now = new Date();Long codeTime = Long.valueOf(session.getAttribute("codeTime")+"");if(StringUtils.isEmpty(checkCode) || captcha == null || !(checkCode.equalsIgnoreCase(captcha))) {request.setAttribute("errorMsg", "验证码错误!");return "验证码错误!";} else if ((now.getTime()-codeTime)/1000/60>5) {//验证码有效时长为5分钟request.setAttribute("errorMsg", "验证码已失效,请重新输入!");return "验证码已失效,请重新输入!";}else {session.removeAttribute("simpleCaptcha");return "1";} }
参考:
http://blog.csdn.net/u014104286/article/details/70515004
http://blog.csdn.net/liunian02050328/article/details/53462053
http://www.jb51.net/article/115800.htm
http://blog.csdn.net/rambo_china/article/details/7720181
http://www.jianshu.com/p/7a37077a41e4
http://www.voidcn.com/article/p-ewnhqlod-bmc.html
==>如有问题,请联系我:easonjim#163.com,或者下方发表评论。<==
Spring Boot中验证码实现kaptcha相关推荐
- spring boot 图文验证码(Kaptcha)使用
用法: 可以直接去官网http://code.google.com/p/kaptcha/下载jar,或者在pom.xml中导入 <dependency><groupId>com ...
- Spring Boot 中使用@Async实现异步调用,加速任务执行!
欢迎关注方志朋的博客,回复"666"获面试宝典 什么是"异步调用"?"异步调用"对应的是"同步调用",同步调用指程序按照 ...
- Spring Boot中使用MongoDB数据库
MongoDB简介 MongoDB是一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库之间的产品,其主要目标是在键/值存储方式(提供了高性能和高度伸缩性)和传统的RDBMS系统(具有 ...
- 再谈Spring Boot中的乱码和编码问题
编码算不上一个大问题,即使你什么都不管,也有很大的可能你不会遇到任何问题,因为大部分框架都有默认的编码配置,有很多是UTF-8,那么遇到中文乱码的机会很低,所以很多人也忽视了. Spring系列产品大 ...
- 【spring boot2】第8篇:spring boot 中的 servlet 容器及如何使用war包部署
嵌入式 servlet 容器 在 spring boot 之前的web开发,我们都是把我们的应用部署到 Tomcat 等servelt容器,这些容器一般都会在我们的应用服务器上安装好环境,但是 spr ...
- Spring Boot 中使用 MongoDB 增删改查
本文快速入门,MongoDB 结合SpringBoot starter-data-mongodb 进行增删改查 1.什么是MongoDB ? MongoDB 是由C++语言编写的,是一个基于分布式文件 ...
- 徒手解密 Spring Boot 中的 Starter自动化配置黑魔法
我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小 ...
- Maven中的profile和spring boot中的profile进行结合
2019独角兽企业重金招聘Python工程师标准>>> 有一些应用,采用了spring boot和spring boot profile.然后想把maven 中的profile和sp ...
- Spring Boot中使用JavaMailSender发送邮件
相信使用过Spring的众多开发者都知道Spring提供了非常好用的JavaMailSender接口实现邮件发送.在Spring Boot的Starter模块中也为此提供了自动化配置.下面通过实例看看 ...
最新文章
- Android 动画之View动画效果和Activity切换动画效果
- ovs-ofctl: s1 is not a bridge or a socket 解决方法
- SharePreference源码学习和多进程的场景
- linux如何找到桌面,我怎样才能找到我正在使用的桌面环境?
- 产品经理和UX设计师,变革已可期
- Java 获取当前项目的类路径
- Adobe Acrobat Pro设置高亮快捷键
- 一个 冒泡排序 和 选择排序 的简单c程序
- 学用 ASP.Net 之 System.Collections.Generic 下的容器类
- 根据银行卡账号获取所属银行php
- DSP入门必看(上)
- linux仿win7软件,Ubuntu/Linux Mint用上仿Win7/Win8主题
- c语言while的用法四种句型,有关while的几种用法
- java开发工具排名_排名前16的Java工具类
- 通信中带宽与数据传输速率的联系与区别
- 点击链接跳转到微信公众号关注页、微信关注链接
- Summer——从头开始写一个简易的Spring框架
- php lumen 框架优点,微框架Lumen 特性
- 2012服务器系统设,server2012服务器安装及设置
- 玩吃鸡台式计算机配置,玩吃鸡的电脑配置推荐_玩吃鸡的电脑配置最低要多少...