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

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&low
				r1 = 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即可。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-28 05:57:49

【JavaWeb】(11)Java实现验证码制作的相关文章

Java实现验证码制作之一自己动手

以前弄验证码都是现找现用,下面是自己跟着敲代码弄好的,记录一下,分享给大家. 我这里用的是Servlet ,Servlet代码如下 import java.awt.Color;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.

Java实现验证码制作之一Kaptcha验证码

Kaptcha验证码 是google提供的验证码插件,使用起来相对简单,设置的干扰线以及字体扭曲不易让其他人读取破解. 这里我们需要 导入一个 kaptcha-2.3.jar  下载地址:http://pan.baidu.com/s/1dDzw7Bj jar包中有个 KaptchaServlet 的servlet,每次访问都会保存在session 作用域当中 默认保存的名称是 KAPTCHA_SESSION_KEY 你也可以自己设定 保存过名称 看xml中的注释的   “session中存放验证

浅尝Java验证码制作(上)

相信大家对验证码这玩意不会陌生,无论是申请账号还是某些情况下登录时都会要求输入验证码.经过统计,验证码一次验证就成功通过的概率是90%,并不高,那么很多人对于这种降低用户体验度的设计肯定会怀疑他的必要性,但黑格尔说过:凡是合乎理性的东西都是现实的:凡是现实的东西都是合乎理性的.接下来我们来了解一下验证码. 验证码是一种区别用户是计算机还是人的公共全自动程序,他被用于防止恶意破解密码.刷票.论坛灌水,防止黑客通过暴力破解方式不断地登录,应用于银行.社区.论坛.投票系统等等. 废话不多说我们来看看我

Java实现验证码的制作

验证码概述 为什么使用验证码? 验证码(CAPTCHA)是一种全自动程序.主要是为了区分“进行操作的是不是人”.如果没有验证码机制,将会导致以下的问题: 对特定网站不断进行登录,破解密码: 对某个网站创建账户: 对某个网站提交垃圾数据(灌水贴): 对某个网站进行刷票. 使用Servlet实现验证码 一个验证码包含两个部分:图片和输入框. 1 <script type="text/javascript"> 2 function reloadCode(){ 3 var time

java生成验证码

一:需求分析 使用java生成验证码: 1:生成画布,画好背景图 2:画随机数 3:画干扰线 4:将内存中的图片保存到硬盘上 二:代码如下 1 /** 2 * 3 */ 4 package com.hlcui.io; 5 6 import java.awt.Color; 7 import java.awt.Font; 8 import java.awt.Graphics; 9 import java.awt.image.BufferedImage; 10 import java.io.File;

动态验证码制作(RandomCodeImage )

在很多的网页中,他们的登录,注册等等地方都有验证码的存在,这下验证码都是动态生成的,有些验证码模糊不堪,有些干扰很多, 而验证码是用来干什么的呢?防止人为输入的不安全?错,验证码真正的用途在于,防止机器的识别,所以,验证码往往都是图片格式的, 人可以识别出来,而机器就识别不出来,这样就可以防止机器识别,就可以保证正在操作的是人,而并不是机器的操作,安全性更高: 下面就分享一下我自己写得一个简单的验证码制作的代码!希望可以一起学习,有什么不足,敬请指正: 这是我封装的一个验证码制作的java类:

使用java解析和制作二维码

项目结构 文件源码 QR.zip 第一步:导入zxing的两个架包 core.jar和javase.jar 第二步:使用工具类 MatrixToImageWriter.java 1 package util; 2 import com.google.zxing.common.BitMatrix; 3 import javax.imageio.ImageIO; 4 import java.io.File; 5 import java.io.OutputStream; 6 import java.i

网站验证码制作

asp.net验证码制作 using System; using System.IO; using System.Drawing; using System.Drawing.Imaging; using System.Text; using System.Collections; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebPa

java登录验证码

一.创建web项目 使用简单servlet来演示java验证码图片生成,servlet简单使用参考http://www.cnblogs.com/ywlaker/p/6038676.html 二.生成验证码 创建VcodeObject.java,存储验证码与图片 package com.demo.vcode; import java.io.InputStream; public class VcodeObject { private String code; private InputStream