学会这个工具的使用,让你快速生成验证码
前言
验证码是我们做人机验证最常用的方式,常用于敏感操作的验证,比如:登录、注册、修改等。
验证码的原理:不同的客户端拥有不同的 session 对象,在看到验证码图片的时刻,服务器后端代码生成图片并将随机字符存储到 session 中。这样客户端看到的只能是图片,人工识别图片后将字符发送到服务器与 session 中的字符进行比对。
上面只是简单的介绍了验证码的原理,更多细节还需有 javaweb 相关基础知识,这篇文章适合有基础的同学。
最近几天我翻到了以前生成验证码的工具类,使用 Graphics2D 生成的图片,然后再以流的形式写出到客户端,这些代码还是有些问题的,都是硬编码。在以后的使用中我们可能有不同的需求都会导致代码重新修改,自定义一些样式都不是很方便。
所以我找到了 github 上的一个生成验证码的工具:kaptcha,下面我就给大家介绍一下 kaptcha 的使用。
kaptcha 的使用
我们就以一个 maven 构建的 web 项目为例
1、依赖 jar 包
在 pom.xml 文件中添加相关依赖
<dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency>
2、配置生成验证码的 servlet
修改 web.xml,添加 kaptcha 提供的 servlet 并配置映射路径
<servlet> <servlet-name>Kaptcha</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Kaptcha</servlet-name> <url-pattern>/captcha</url-pattern> </servlet-mapping>
访问 http://localhost:8080/captcha 这时发现就已经可以产生验证码了,但还有个问题,验证码的随机字符存在哪里了?
3、探索 kaptcha
我们来查看 KaptchaServlet 这个类的源码,doGet 方法
@Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Set to expire far in the past. resp.setDateHeader("Expires", 0); // Set standard HTTP/1.1 no-cache headers. resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); // Set IE extended HTTP/1.1 no-cache headers (use addHeader). resp.addHeader("Cache-Control", "post-check=0, pre-check=0"); // Set standard HTTP/1.0 no-cache header. resp.setHeader("Pragma", "no-cache"); // return a jpeg resp.setContentType("image/jpeg"); // create the text for the image String capText = this.kaptchaProducer.createText(); // store the text in the session req.getSession().setAttribute(this.sessionKeyValue, capText); // store the date in the session so that it can be compared // against to make sure someone hasn't taken too long to enter // their kaptcha req.getSession().setAttribute(this.sessionKeyDateValue, new Date()); // create the image with the text BufferedImage bi = this.kaptchaProducer.createImage(capText); ServletOutputStream out = resp.getOutputStream(); // write the data out ImageIO.write(bi, "jpg", out); }
有这样一段代码,获取字符后存入 session 中,键为 sessionKeyValue
这个变量的值
// create the text for the image String capText = this.kaptchaProducer.createText(); // store the text in the session req.getSession().setAttribute(this.sessionKeyValue, capText);
sessionKeyValue
这个变量的值在 init 方法中被赋值
this.sessionKeyValue = config.getSessionKey();
好我们进入 config.getSessionKey()
中查看代码,发现 session 的键为 Constants 这个类中的常量 Constants.KAPTCHA_SESSION_KEY
return this.properties.getProperty(Constants.KAPTCHA_SESSION_CONFIG_KEY, Constants.KAPTCHA_SESSION_KEY);
4、编写测试验证码是否正常使用的 servlet
我们来验证一下,编写一个 servlet
import com.google.code.kaptcha.Constants; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/test") public class TestKaptchaServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); //获取传入的验证码 String captcha = req.getParameter("captcha"); if (null != captcha) { //获取实际session中的验证码 String code = (String) req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); if (null == code){ resp.sendRedirect("/captcha"); return; } if (code.equalsIgnoreCase(captcha)) { out.print("验证输入正确"); } else { out.print("验证码输入有误"); } } else { out.print("必须输入验证码"); } out.flush(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
先访问验证码 http://localhost:8080/captcha 然后访问 http://localhost:8080/test?captcha=验证码
以上这些默认配置能满足一般业务的使用了,下面通过深入解析 kaptcha 的源码自定义配置验证码的宽、高、边框、颜色、字符等
5、深入源码自定义配置 kaptcha
再来看一下 init 方法中的代码
@Override public void init(ServletConfig conf) throws ServletException { super.init(conf); // Switch off disk based caching. ImageIO.setUseCache(false); Enumeration<?> initParams = conf.getInitParameterNames(); while (initParams.hasMoreElements()) { String key = (String) initParams.nextElement(); String value = conf.getInitParameter(key); this.props.put(key, value); } Config config = new Config(this.props); this.kaptchaProducer = config.getProducerImpl(); this.sessionKeyValue = config.getSessionKey(); this.sessionKeyDateValue = config.getSessionDate(); }
这段代码获取 servlet 的初始化参数,并将参数存入 config 对象中,看 config 中的一段代码
public boolean isBorderDrawn() { String paramName = Constants.KAPTCHA_BORDER; String paramValue = this.properties.getProperty(paramName); return this.helper.getBoolean(paramName, paramValue, true); }
没错,所有的参数名字都是 Constants 类中常量名称
public class Constants { public final static String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY"; public final static String KAPTCHA_SESSION_DATE = "KAPTCHA_SESSION_DATE"; public final static String KAPTCHA_SESSION_CONFIG_KEY = "kaptcha.session.key"; //省略其他代码 }
所以,可以给 KaptchaServlet
在 web.xml 配置参数,下面这些配置给大家参考
<servlet> <servlet-name>Kaptcha</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> <!-- 是否有边框 --> <init-param> <param-name>kaptcha.border</param-name> <param-value>no</param-value> </init-param> <!-- 字体颜色 --> <init-param> <param-name>kaptcha.textproducer.font.color</param-name> <param-value>red</param-value> </init-param> <!-- 图片宽度 --> <init-param> <param-name>kaptcha.image.width</param-name> <param-value>135</param-value> </init-param> <!-- 使用哪些字符生成验证码 --> <init-param> <param-name>kaptcha.textproducer.char.string</param-name> <param-value>ACDEFHKPRSTWX345679</param-value> </init-param> <!-- 图片高度 --> <init-param> <param-name>kaptcha.image.height</param-name> <param-value>50</param-value> </init-param> <!-- 字体大小 --> <init-param> <param-name>kaptcha.textproducer.font.size</param-name> <param-value>38</param-value> </init-param> <!-- 干扰线的颜色 --> <init-param> <param-name>kaptcha.noise.color</param-name> <param-value>black</param-value> </init-param> <!-- 字符个数 --> <init-param> <param-name>kaptcha.textproducer.char.length</param-name> <param-value>6</param-value> </init-param> <!-- 使用哪些字体 --> <init-param> <param-name>kaptcha.textproducer.font.names</param-name> <param-value>Arial</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Kaptcha</servlet-name> <url-pattern>/captcha</url-pattern> </servlet-mapping>
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
SpringMVC源码阅读系列汇总
SpringMVC源码阅读系列汇总 1.前言 1.1 导入 SpringMVC是基于Servlet和Spring框架设计的Web框架,做JavaWeb的同学应该都知道 本文基于Spring4.3.7源码分析,(不要被图片欺骗了,手动滑稽),Spring官网告诉我们,Spring可以构建基于JVM的Servlet程序。Spring初代版本在2003年由Rod Johnson所写 以下摘自维基百科 TheSpring Frameworkis an application framework and inversion of controlcontainerfor theJava platform. The framework's core features can be used by any Java application, but there are extensions for building web applications on top of theJava EE(Enterprise Edition) platform. Although the framework doe...
- 下一篇
eclipse中使用hibernate对mysql进行增删改查
数据库操作前后的一些必须的操作进行数据库操作前: //生成会话工厂 SessionFactory sf = new Configuration().configure().buildSessionFactory(); //从会话工厂中获取一个会话 Session s = sf.openSession(); //开始事务 s.beginTransaction(); 数据库操作之后: //对事物进行提交 s.getTransaction().commit(); //首先关闭会话 s.close(); //最后关闭会话工厂 sf.close(); 增 //向product_表中插入10条记录 for (int i = 0; i < 10; i++) { Product p = new Product(); p.setName("iphone"+i); p.setPrice(i); s.save(p); } 删 Product p =(Product) s.get(Product.class, 5); s.delete(p); 改 Product p =(Product) s.get(P...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,CentOS7官方镜像安装Oracle11G