使用servlet生成动态验证码

今天看到很多地方使用图片验证码,想想自己还从没写过这方面程序,于是打算尝试一下
应该说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() {
 }
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据