手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>Java技术>列表

使用技巧:Java实现随机验证码功能实例

来源:互联网 作者:west263.com 时间:2008-02-23
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

现在许多系统的注册、登录或者发布信息模块都添加的随机码功能,就是为了避免自动注册程序或者自动发布程序的使用。

验证码实际上就是随机选择一些字符以图片的形式展现在页面上,如果进行提交操作的同时需要将图片上的字符同时提交,如果提交的字符与服务器session保存的不同,则认为提交信息无效。为了避免自动程序分析解析图片,通常会在图片上随机生成一些干扰线或者将字符进行扭曲,增加自动识别的难度。

在这里,我们使用servlet来实现随机验证码的实现。

package com.servlet;



import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.util.Random;



import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;



/**

 * 生成随机验证码

 * @author bitiliu

 *

 */

public class ValidateCodeServlet extends HttpServlet 

{



 private static final long serialVersionUID = 1L;

 

 //验证码图片的宽度。

    private int width=60;

    //验证码图片的高度。

    private int height=20;

    //验证码字符个数

    private int codeCount=4;

    

    

    private int x=0;

    //字体高度

    private int fontHeight;    

    private int codeY;

    

    char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',

   'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',

   'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

    

    /**

     * 初始化验证图片属性

     */

    public void init() throws ServletException

 {

     //从web.xml中获取初始信息

     //宽度

  String strWidth=this.getInitParameter("width");

  //高度

  String strHeight=this.getInitParameter("height");

  //字符个数

  String strCodeCount=this.getInitParameter("codeCount"); 

  

  //将配置的信息转换成数值

  try

  {

   if(strWidth!=null && strWidth.length()!=0)

   {

    width=Integer.parseInt(strWidth);

   }

   if(strHeight!=null && strHeight.length()!=0)

   {

    height=Integer.parseInt(strHeight);

   }

   if(strCodeCount!=null && strCodeCount.length()!=0)

   {

    codeCount=Integer.parseInt(strCodeCount);

   }

  }

  catch(NumberFormatException e)

  {}

  

  x=width/(codeCount 1);

  fontHeight=height-2;

  codeY=height-4;

  

 }

    

    protected void service(HttpServletRequest req, HttpServletResponse resp)

   throws ServletException, java.io.IOException {

     

     //定义图像buffer

  BufferedImage buffImg = new BufferedImage(

width, height,BufferedImage.TYPE_INT_RGB);

  Graphics2D g = buffImg.createGraphics();



  //创建一个随机数生成器类

  Random random = new Random();



  //将图像填充为白色

  g.setColor(Color.WHITE);

  g.fillRect(0, 0, width, height);



  //创建字体,字体的大小应该根据图片的高度来定。

  Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);

  //设置字体。

  g.setFont(font);



  //画边框。

  g.setColor(Color.BLACK);

  g.drawRect(0, 0, width - 1, height - 1);



  //随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。

  g.setColor(Color.BLACK);

  for(int i = 0; i < 160; 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);

  }



  //randomCode用于保存随机产生的验证码,以便用户登录后进行验证。

  StringBuffer randomCode = new StringBuffer();

  int red = 0, green = 0, blue = 0;



  //随机产生codeCount数字的验证码。

  for (int i = 0; i < codeCount; i  ) {

   //得到随机产生的验证码数字。

   String strRand = String.valueOf(codeSequence[random.nextInt(36)]);

   //产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。

   red = random.nextInt(255);

   green = random.nextInt(255);

   blue = random.nextInt(255);



   //用随机产生的颜色将验证码绘制到图像中。

   g.setColor(new Color(red, green, blue));

   g.drawString(strRand, (i   1) * x, codeY);



   //将产生的四个随机数组合在一起。

   randomCode.append(strRand);

  }

  // 将四位数字的验证码保存到Session中。

  HttpSession session = req.getSession();

  session.setAttribute("validateCode", randomCode.toString());



  // 禁止图像缓存。

  resp.setHeader("Pragma", "no-cache");

  resp.setHeader("Cache-Control", "no-cache");

  resp.setDateHeader("Expires", 0);



  resp.setContentType("image/jpeg");



  //将图像输出到Servlet输出流中。

  ServletOutputStream sos = resp.getOutputStream();

  ImageIO.write(buffImg, "jpeg", sos);

  sos.close();

 }



}

需要在web.xml中声明servlet

<servlet>

 <servlet-name>ValidateCodeServlet</servlet-name>

 <servlet-class>com.servlet.ValidateCodeServlet</servlet-class>

 <init-param>

  <param-name>width</param-name>

  <param-value>200</param-value>

 </init-param>

 <init-param>

  <param-name>height</param-name>

  <param-value>80</param-value>

 </init-param>

 <init-param>

  <param-name>codeCount</param-name>

  <param-value>5</param-value>

 </init-param>

  </servlet>



  <servlet-mapping>   

 <servlet-name>ValidateCodeServlet</servlet-name>   

 <url-pattern>/validateCodeServlet</url-pattern>   

  </servlet-mapping>

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!