Java 随机生成验证码(支持大小写字母、数字、随机字体)的实例
代码如下所示:
package com.hoo.util;
import java.awt.color;
import java.awt.font;
import java.awt.graphics;
import java.awt.image.bufferedimage;
import java.util.random;
import javax.imageio.imageio;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
/**
* <b>function:</b> 验证码生成工具类
* @project networkservice
* @package com.hoo.util
* @filename validcodeutils.java
* @createdate 2010-8-3 下午03:05:50
* @author hoojo
*/
@suppresswarnings("unused")
public class validcodeutils {
/*********************************************************************
* 验证码宽度
*/
public static int width = 60;
/***
* 验证码高度
*/
public static int height = 20;
/**********************************************************************
* 验证码背景颜色color_fc_bg 应当小于color_bc_bg
*/
public static int color_fc_bg = 200;
/***
* 验证码背景颜色color_fc_bg 应当小于color_bc_bg
*/
public static int color_bc_bg = 250;
/**********************************************************************
* 验证码背景干扰线颜色color_fc_line 应当小于color_bc_line
*/
public static int color_fc_line = 160;
/***
* 验证码背景干扰线颜色color_fc_line 应当小于color_bc_line
*/
public static int color_bc_line = 200;
/***************************************************************************
* 验证码颜色color_fc_code 应当小于color_bc_code
*/
public static int color_fc_code = 20;
/***
* 验证码颜色color_fc_code 应当小于color_bc_code
*/
public static int color_bc_code = 170;
/***************************************************************************
* 生成在指定范围内的颜色
* @param fc 范围fc color值 小于255
* @param bc 范围bc color值 小于255
* @return color
*/
private static color getrandcolor(int fc, int bc) {
random random = new random();
if (fc < 0)
fc = 0;
if (bc < 0)
bc = 1;
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
if (bc == fc)
bc += 10;
int temp = 0;
if (bc < fc) {
temp = bc;
bc = fc;
fc = temp;
}
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);
}
/**
* <b>function:</b> 生成图片方法
* @createdate 2010-8-3 下午03:06:22
* @author hoojo
* @param request httpservletrequest
* @param response httpservletresponse
* @return boolean
* @throws exception
*/
public static boolean getimage(httpservletrequest request, httpservletresponse response) throws exception{
response.reset();
response.setcontenttype("image/jpeg");
// 设置页面不缓存
response.setheader("pragma", "no-cache");
response.setheader("cache-control", "no-cache");
response.setdateheader("expires", 0);
// 在内存中创建图象
bufferedimage image = new bufferedimage(width, height, bufferedimage.type_int_rgb);
// 获取图形上下文
graphics img = image.getgraphics();
// 生成随机类
random random = new random();
// 设定背景色
img.setcolor(getrandcolor(color_fc_bg, color_bc_bg));
img.fillrect(0, 0, width, height);
// 设定字体
img.setfont(new font("times new roman", font.plain, 18));
// 画边框
// g.setcolor(new color());
// g.drawrect(0,0,width-1,height-1);
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
img.setcolor(getrandcolor(color_fc_line, color_bc_line));
for (int i = 0; i < 155; i++) {
int x = random.nextint(width);
int y = random.nextint(height);
int xl = random.nextint(12);
int yl = random.nextint(12);
img.drawline(x, y, x + xl, y + yl);
}
// 取随机产生的认证码(4位数字)
string codevalue = "";
for (int i = 0; i < 4; i++) {
//string rand = string.valueof(random.nextint(10));
string rand = getrandomchar();
codevalue = codevalue.concat(rand);
img.setfont(getrandomfont());//随机字体
// 将认证码显示到图象中
img.setcolor(getrandcolor(color_fc_code, color_bc_code));
img.drawstring(rand, 13 * i + 6, 16);
}
request.getsession().setattribute("codevalue", codevalue);
// 图象生效
img.dispose();
// 输出图象到页面
return imageio.write(image, "jpeg", response.getoutputstream());
}
/**
* 随机生成字符,含大写、小写、数字
* <b>function:</b> 功能
* @createdate 2010-8-23 上午10:33:55
* @author hoojo
* @return
*/
public static string getrandomchar() {
int index = (int) math.round(math.random() * 2);
string randchar = "";
switch (index) {
case 0://大写字符
randchar = string.valueof((char)math.round(math.random() * 25 + 65));
break;
case 1://小写字符
randchar = string.valueof((char)math.round(math.random() * 25 + 97));
break;
default://数字
randchar = string.valueof(math.round(math.random() * 9));
break;
}
return randchar;
}
/**
* <b>function:</b> 随机生成字体、文字大小
* @createdate 2010-8-23 上午10:44:22
* @author hoojo
* @return
*/
public static font getrandomfont() {
string[] fonts = {"georgia", "verdana", "arial", "tahoma", "time news roman", "courier new", "arial black", "quantzite"};
int fontindex = (int)math.round(math.random() * (fonts.length - 1));
int fontsize = (int) math.round(math.random() * 4 + 16);
return new font(fonts[fontindex], font.plain, fontsize);
}
}
其中验证码的值是保存在session中:request.getsession().setattribute("codevalue", codevalue);
比较用户输入的值和session中的codevalue是否相等即可;
下面是jsp页面调用servlet:validcodeservlet.java
validcodeservlet中调用了上面的validcodeutils 验证码生成工具类
package com.hoo.servlet;
import java.io.ioexception;
import javax.servlet.servletexception;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import com.hoo.util.validcodeutils;
@suppresswarnings("serial")
public class validcodeservlet extends httpservlet {
public void doget(httpservletrequest request, httpservletresponse response)
throws servletexception, ioexception {
try {
validcodeutils.getimage(request, response);
} catch (exception e) {
e.printstacktrace();
}
}
public void dopost(httpservletrequest request, httpservletresponse response)
throws servletexception, ioexception {
doget(request, response);
}
}
jsp页面调用servlet方法即可
js:reloadvalidcode方法
function reloadvalidcode(o) {
o.src = "${pagecontext.request.contextpath }/validcodeservlet?timed=" + new date().getmilliseconds();
}
这里的"timed=" + new date().getmilliseconds();是需要防止ie缓存用的
html标签:
<img src="${pagecontext.request.contextpath }/validcodeservlet" title="看不清,点击刷新" onclick="reloadvalidcode(this)"/>
直接跟servlet名称配置的url即可,和web.xml配置对应。主要调用路径${pagecontext.request.contextpath }/validcodeservlet这样会带上根目录,比较保险。
web.xml中validcodeservlet配置
<servlet>
<servlet-name>validcodeservlet</servlet-name>
<servlet-class>com.hoo.servlet.validcodeservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>validcodeservlet</servlet-name>
<url-pattern>/validcodeservlet</url-pattern>
</servlet-mapping>