今天看到很多地方使用图片验证码,想想自己还从没写过这方面程序,于是打算尝试一下
应该说java实现这个功能还是比较方便的。servlet可以直接指定输出类型为图形,这样我们就可以指定输出类型为"image/jpeg",而画图更不是问题,自带库功能已经足够了,简单的实现应该是这样,先设置输出类型image/jpeg.
创建一个BufferedImage对象,然后在里面画图,画完后取得OutputStream,然后往OutputStream里面输出既可,当然这种生成验证码实用性不大,现在的程序OCR很是厉害,仅仅把文字改成图片形式起不了什么大作用,得加上底色,纹路,文字变形变色,而且每个session都要生成一个单独的验证码.所以要把验证码存入session,使用session的setAttribute和getAttribute就可以实现,思路明确了剩下就好办,编码实现部分近两日补上.
8月18日14点02分
基本上完成功能,但是还有些小bug
目前主要需解决以下问题
按后退按钮的时候验证码不更新
考虑的解决方案。
禁制缓存,网页即时过期,
使用<body onload="javascript:onBodyLoad();">这样的方法强制更新。
–8月18日19点56分
问题已解决。在生成图片的servlet中设置response属性既可
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
原先在显示图片的页面中设此属性后退时图片不会自动更新。
配置实现动态修改
将数据库配置等设置存在一xml文件中以解决维护问题。
–8月18日20点56分完成配置保存在servlet配置文件web.xml中,
完成url mapping,完成autoreload,今天一天收获挺大,完整代码整理优化后发布
将设置保存在一单独配置xml文件中,
2006-09-01 v0.1
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;
public class AuthenCode
extends HttpServlet {
private static final String CONTENT_TYPE = "image/jpeg"; // 输出的文件格式是jpeg ,关于HTTP输出类型的定义可参考相关文档说明
private static final int WIDTH = 40;
private static final int HEIGHT = 18;
private static final int LENGTH = 4;
//Initialize global variables
public void init() throws ServletException {
}
//Process the HTTP Get request
public 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);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
response.setContentType(CONTENT_TYPE); //定义输出的文件格式。
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
OutputStream out = response.getOutputStream();
Random random = new Random();
int width = WIDTH;
int height = HEIGHT;
int length = LENGTH;
HttpSession session = request.getSession(true);
try {
width = Integer.parseInt(request.getParameter("width"));
}
catch (Exception ex) {
width = WIDTH;
}
try {
height = Integer.parseInt(request.getParameter("heigth"));
}
catch (Exception ex) {
height = HEIGHT;
}
try {
length = Integer.parseInt(request.getParameter("length"));
}
catch (Exception ex) {
length = LENGTH;
}
//取得随机整数
Random ran = new Random(System.currentTimeMillis());
//取除第一位后的指定几位
String seed = (ran.nextInt() + "").substring(1, 1 + length);
//将取得的保存在session中
session.setAttribute("authCode", seed);
//生成缓冲图象
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
//取得绘图对象
Graphics g = image.getGraphics();
g.setColor(new Color(245, 245, 245));
//填充背景色
g.fillRect(0, 0, width, height);
g.setColor(getrandcolor(160,200));
for (int i=0;i<50;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);
}
//写入指定文字
//设置字体颜色
g.setColor(Color.DARK_GRAY);
//设置字体样式
g.setFont(new Font("Arial", Font.BOLD, 12));
g.drawString(seed, 4, 13);
g.dispose();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
}
//Clean up resources
public void destroy() {
}
}