【JavaWeb】(11)Java实现验证码制作

来源:互联网 发布:现在开淘宝店还挣钱吗 编辑:程序博客网 时间:2024/06/05 00:54

1. 使用Servlet实现验证码

首先创建工程,实现jsp代码:

<script type="text/javascript">function reloadCode() {var time = new Date().getTime();document.getElementById("image_code").src = "<%=path%>/servlet/ImageServlet?d="+ time;}</script></head><body>验证码:<input type="text" name="check_code"><img id="image_code" alt="验证码"src="<%=request.getContextPath()%>/servlet/ImageServlet"><a href="javascript:reloadCode();">看不清楚</a><br></body>
重新加载的函数有一个d的参数,这是为了防止传相同的地址浏览器无法刷新。可以看出我们的img标签使用的是Servlet来填充的,接下来是我们的ImageServlet:
<span style="white-space:pre"></span>protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);Graphics g = bi.getGraphics();Color c = new Color(200, 150, 255);g.setColor(c);g.fillRect(0, 0, 68, 22);// 生成26个英文字母的数组char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();// 随机获取4个字符Random r = new Random();int len = ch.length;int index = 0;StringBuffer sb = new StringBuffer();for (int i = 0; i < 4; i++) {index = r.nextInt(len);g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));g.drawString(ch[index] + "", i * 15 + 3, 18);sb.append(ch[index]);}req.getSession().setAttribute("check_code", sb.toString());ImageIO.write(bi, "JPG", resp.getOutputStream());}
只用重写Servlet的doGet方法就可以了。

接下来是验证验证码:

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=utf-8");String checkCode = (String) request.getSession().getAttribute("check_code");String userCode = request.getParameter("check_code");PrintWriter out = response.getWriter();if (checkCode.equals(userCode)) {out.print("验证码输入正确");} else {out.print("验证码输入错误");}out.close();}
如果不想区分大小写的话,在获取userCode的时候可以统一转换成大写即可。


2. 使用Jcaptcha组件实现验证码

Jcaptcha是一个用来生成图形验证码的Java开源组件,使用起来也是非常的简单方便。常常与Spring组合使用,可以产生多种形式的验证码。
Jcaptcha是一个开源的组件,先是jsp代码:

<form action="submit.action" method="post">     <img src="jcaptcha.jpg" /> <input type="text" name="japtcha" value="" />     <input type="submit"/></form>
然后需要导入几个这个开源的jar包,后面工程里都有。

然后配置web.xml

<web-app><display-name>Simple Image Captcha Servlet Sample</display-name><servlet><servlet-name>jcaptcha</servlet-name><servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class></servlet><servlet><servlet-name>submit</servlet-name><servlet-class>com.octo.captcha.module.servlet.image.sample.SubmitActionServlet</servlet-class></servlet><servlet-mapping><servlet-name>jcaptcha</servlet-name><url-pattern>/jcaptcha.jpg</url-pattern></servlet-mapping><servlet-mapping><servlet-name>submit</servlet-name><url-pattern>/submit.action</url-pattern></servlet-mapping></web-app>
最后是提交servlet的代码:

protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");String userCaptchaResponse = request.getParameter("japtcha");boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse);if (captchaPassed)response.getWriter().write("captcha passed");else {response.getWriter().write("captcha failed");}response.getWriter().write("<a href='index.jsp'>Try again</a>");}
也是很简单。


3. 使用Kaptcha实现验证码

Kaptcha也是一个非常实用的验证码生成工具,有了它,你可以生成各种样式的验证码,因为它是可配置的。

(1). 首先是字母数组组合验证

先导入包kaptcha-2.3.jar,index.jsp:

<form action="check.jsp"><img src="randomcode.jpg"> <input type="text" name="r"><input type="submit" name="s"> <br></form>
在web.xml重配置:

<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>/randomcode.jpg</url-pattern></servlet-mapping>
检测验证码是否正确的check.jsp:

<%// 检查是否是正确的验证码String k = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);String str = request.getParameter("r");if (k.equals(str)) {out.print("true");}out.print(k + "---" + str);%>
(2). Kaptcha的详细配置

在web.xml中的<servlet>标签的<init-param>标签内,可以配置多个设置:

1). 是否加入边框:

<description>图片边框,合法值:yes,no</description><param-name>kaptcha.border</param-name><param-value>yes</param-value>
2). 设置边框颜色:
<description>边框颜色,合法值:white、black、blue等</description><param-name>kaptcha.border.color</param-name><param-value>black</param-value>

3). 边框厚度:

<description>边框厚度,合法值:0等</description><param-name>kaptcha.border.thickness</param-name><param-value>1</param-value>

3). 图片宽度:

<description>图片宽度</description><param-name>kaptcha.image.width</param-name><param-value>100</param-value>

4). 图片高度:

<description>图片高度</description><param-name>kaptcha.image.height</param-name><param-value>50</param-value>

5). 图片实现类:

<description>图片实现类</description><param-name>kaptcha.producer.impl</param-name><param-value>com.google.code.kaptcha.implDefaultKaptcha</param-value>

6). 文本实现类:

<description>文本实现类</description><param-name>kaptcha.textproducer.impl</param-name><param-value>com.google.code.kaptcha.text.implDefaultTextCreator</param-value>

7). 验证码配置:

<description>文本集合,验证码值从此集合中获取</description><param-name>kaptcha.textproducer.char.string</param-name><param-value>abcde234567gfmnopq</param-value>

8). 验证码长度:

<description>验证码长度 5</description><param-name>kaptcha.textproducer.char.length</param-name><param-value>2</param-value>

9). 验证码字体:

<description>字体Arial,Courier</description><param-name>kaptcha.textproducer.font.names</param-name><param-value>Arial, Courier</param-value>

10). 验证码字体大小:

<description>字体大小40px</description><param-name>kaptcha.textproducer.font.size</param-name><param-value>40</param-value>

11). 验证码字体颜色:

<description>字体颜色,合法值:white、black等</description><param-name>kaptcha.textproducer.font.color</param-name><param-value>black</param-value>

12). 验证码文字间隔:

<description>文字间隔</description><param-name>kaptcha.textproducer.char.space</param-name><param-value>2</param-value>

13). 验证码干扰实现类:

<description>干扰实现类</description><param-name>kaptcha.noise.impl</param-name><param-value>com.google.code.kaptcha.impl.DefaultNoise</param-value>

14). 干扰颜色:

<description>干扰颜色,合法值:r, g, b或者black等</description><param-name>kaptcha.noise.color</param-name><param-value>black</param-value>

15). 验证码图片样式:

<description>图片样式:水纹com.google.code.kaptcha.impl.WaterRipple、鱼眼com.google.code.kaptcha.impl.FishEyeGimpy、阴影com.google.code.kaptcha.impl.ShadowGimpy等</description><param-name>kaptcha.obscurificator.impl</param-name><param-value>com.google.code.kaptcha.impl.WaterRipple</param-value>

16). 背景实现类:

<description>背景实现类</description><param-name>kaptcha.background.impl</param-name><param-value>com.google.code.kaptcha.impl.DefaultBackground</param-value>

17). 背景颜色渐变-开始颜色:

<description>颜色渐变-开始颜色</description><param-name>kaptcha.background.clear.from</param-name><param-value>green</param-value>

18). 背景颜色渐变-结束颜色:

<description>颜色渐变-结束颜色</description><param-name>kaptcha.background.clear.to</param-name><param-value>white</param-value>

19). 文字渲染器:

<description>文字渲染器</description><param-name>kaptcha.word.impl</param-name><param-value>com.google.code.kaptcha.text.impl.DefaultWordRenderer</param-value>

20). 验证码在session中存放验证码的key键配置:

<description>session中存放验证码的key键</description><param-name>kaptcha.session.key</param-name><param-value>KAPTCHA_SESSION_KEY</param-value>

(3). 中文验证码的实现

首先是我们生成中文的类:

public class ChineseText extends Configurable implements TextProducer {public String getText() {int length = getConfig().getTextProducerCharLength();String finalWord = "", firstWord = "";int tempInt = 0;String[] array = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9","a", "b", "c", "d", "e", "f" };Random rand = new Random();for (int i = 0; i < length; i++) {switch (rand.nextInt(array.length)) {case 1:tempInt = rand.nextInt(26) + 65;firstWord = String.valueOf((char) tempInt);break;case 2:int r1,r2,r3,r4;String strH,strL;// high&lowr1 = rand.nextInt(3) + 11; // 前闭后开[11,14)if (r1 == 13) {r2 = rand.nextInt(7);} else {r2 = rand.nextInt(16);}r3 = rand.nextInt(6) + 10;if (r3 == 10) {r4 = rand.nextInt(15) + 1;} else if (r3 == 15) {r4 = rand.nextInt(15);} else {r4 = rand.nextInt(16);}strH = array[r1] + array[r2];strL = array[r3] + array[r4];byte[] bytes = new byte[2];bytes[0] = (byte) (Integer.parseInt(strH, 16));bytes[1] = (byte) (Integer.parseInt(strL, 16));firstWord = new String(bytes);break;default:tempInt = rand.nextInt(10) + 48;firstWord = String.valueOf((char) tempInt);break;}finalWord += firstWord;}return finalWord;}}
需要继承Configurable类,实现TextProducer接口。然后在web.xml中配置:

<init-param><description>文本实现类</description><param-name>kaptcha.textproducer.impl</param-name><param-value>com.thr.text.ChineseText</param-value></init-param>
注意我们这里要指定类的全名。

如果当输入中文检测出现乱码时,修改check.jsp:

<%// 检查是否是正确的验证码String k = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);String str = request.getParameter("r");str = new String(str.getBytes("ISO-8859-1"), "UTF-8");if (k.equals(str)) {out.print("true");}out.print(k + "---" + str);%>
(4). 算式验证码的实现
我们要写一个Servlet来实现:
public class KaptchaServlet extends HttpServlet implements Servlet {private Properties props;private Producer kaptchaProducer;private String sessionKeyValue;public KaptchaServlet() {this.props = new Properties();this.kaptchaProducer = null;this.sessionKeyValue = null;}public void init(ServletConfig conf) throws ServletException {super.init(conf);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();}public void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {resp.setDateHeader("Expires", 0L);resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");resp.addHeader("Cache-Control", "post-check=0, pre-check=0");resp.setHeader("Pragma", "no-cache");resp.setContentType("image/jpeg");String capText = this.kaptchaProducer.createText();String s1 = capText.substring(0, 1);String s2 = capText.substring(1, 2);int r = Integer.valueOf(s1).intValue() + Integer.valueOf(s2).intValue();req.getSession().setAttribute(this.sessionKeyValue, String.valueOf(r));BufferedImage bi = this.kaptchaProducer.createImage(s1 + "+" + s2+ "=?");ServletOutputStream out = resp.getOutputStream();ImageIO.write(bi, "jpg", out);try {out.flush();} finally {out.close();}}}
然后在web.xml中替换掉我们之前使用的servlet即可。

源码下载


0 0
原创粉丝点击