纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~)

java验证码生成器,自认为还算经典import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
* @(#)VerifyCodeServlet.java Dec 9, 2007 8:14:14 PM
*
* @author Yuan
* 验证码生成器,使用此类需要将表单里的验证码输入框的name属性设为"verifycode"
*/
public class VerifyCodeGenerator {
    
    private static final VerifyCodeGenerator generator = new VerifyCodeGenerator();
    
    private final String ATTRIBUTE_NAME = "verifycode";
    //图片的宽度
    private final int WIDTH = 15;
    //图片的高度
    private final int HEIGHT = 22;
    //字符串长度
    private final int CODE_LENGTH = 4;
    //随机字符串范围
    private final String RAND_RANGE = "abcdefghijklmnopqrstuvwxyz"
        + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        + "1234567890"
        + "@#quot;;
    
    private final char[] CHARS = RAND_RANGE.toCharArray();
    
    private Random random = new Random();
    
    private VerifyCodeGenerator(){
        //
    }
    
    public static VerifyCodeGenerator getInstance(){
        return generator;
    } 
     

    /**
     * 生成随机字符串
     * @return 随机字符串
     */
    private String getRandString(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++)
            sb.append(CHARS[random.nextInt(CHARS.length)]);
        return sb.toString();
    }
    
    /**
     * 生成随机颜色
     * @param ll 产生颜色值下限(lower limit)
     * @param ul 产生颜色值上限(upper limit)
     * @return 生成的随机颜色对象
     */
    private Color getRandColor(int ll, int ul){
        if (ll > 255) ll = 255;
        if (ll < 1) ll = 1;
        if (ul > 255) ul = 255;
        if (ul < 1) ul = 1;
        if (ul == ll) ul = ll + 1;
        int r = random.nextInt(ul - ll) + ll;
        int g = random.nextInt(ul - ll) + ll;
        int b = random.nextInt(ul - ll) + ll;
        Color color = new Color(r,g,b);
        return color;
    }
    
    /**
     * 生成指定字符串的图像数据
     * @param verifyCode 即将被打印的随机字符串
     * @return 生成的图像数据
     * */
    private BufferedImage getImage(String verifyCode){
        
        BufferedImage image = new BufferedImage(WIDTH * CODE_LENGTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        
        //获取图形上下文
        Graphics graphics = image.getGraphics();
        
        //设置背景色
        graphics.setColor(getRandColor(1,50));
        //填充背景色
        graphics.fillRect(0, 0, WIDTH * 4, HEIGHT);
        
        //设置边框颜色
        graphics.setColor(new Color(0,255,0));
        //画边框
        for (int i=0; i<2; i++)
            graphics.drawRect(i, i, WIDTH * CODE_LENGTH - i * 2 - 1, HEIGHT - i * 2 - 1);
        
        //设置随机干扰线条颜色
        graphics.setColor(getRandColor(50,100));
        //产生50条干扰线条
        for (int i=0; i<50; i++){
            int x1 = random.nextInt(WIDTH * CODE_LENGTH - 4) + 2;
            int y1 = random.nextInt(HEIGHT - 4) + 2;
            int x2 = random.nextInt(WIDTH * CODE_LENGTH - 2 - x1) + x1;
            int y2 = y1;
            graphics.drawLine(x1, y1, x2, y2);
        }
        
        //设置字体
        graphics.setFont(new Font("Times New Roman", Font.PLAIN, 18));
        //画字符串
        for (int i=0; i<this.CODE_LENGTH; i++){
            String temp = verifyCode.substring(i, i+1);
            graphics.setColor(getRandColor(100,255));
            graphics.drawString(temp, 13 * i + 6, 16);
        } 
         
        //图像生效
        graphics.dispose();
        
        return image;
    }
    
    /**
     * 将验证码的图像输出
     * @param request 用户的请求对象
     * @param response 用户的响应对象
     * */
    public void printImage(HttpServletRequest request,
            HttpServletResponse response){
        //将ContentType设为"image/jpeg",让浏览器识别图像格式。
        response.setContentType("image/jpeg");
        //设置页面不缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 2000);
        
        //获得随机验证码
        String verifyCode = this.getRandString();
        String str = "ssss";
        for(int i=0; i<10; i++)
            str = str + str;
        //获得验证码的图像数据
        BufferedImage bi = this.getImage(verifyCode);
        //把验证码存入session
        request.getSession().setAttribute(ATTRIBUTE_NAME, verifyCode);
        try{
            //获得Servlet输出流
            ServletOutputStream outStream = response.getOutputStream();
            //创建可用来将图像数据编码为JPEG数据流的编码器
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream);
            //将图像数据进行编码
            encoder.encode(bi);
            //强行将缓冲区的内容输入到页面
            outStream.flush();
            //关闭输出流
            outStream.close();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }
    
    /**
     * 检查输入的验证码是否正确,若用户输入的验证码与生成的验证码相符则返回true,否则返回false。
     * @param request 用户的请求对象
     * @return 验证结果
     * */
    public boolean check(HttpServletRequest request){
        if (((String)request.getParameter(ATTRIBUTE_NAME))
                .equalsIgnoreCase((String)request.getSession().getAttribute(ATTRIBUTE_NAME))){
            request.getSession().removeAttribute(ATTRIBUTE_NAME);
            return true;
        }
        return false;
    }
}
/**此代码为我们群老大深秋小雨
所编写,真的比较实用,来自qq群J道
**/

posted on 2008-04-05 12:40 伍兴佳 阅读(5442) 评论(10)  编辑  收藏

评论

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~)[未登录] 2008-04-05 21:21 子玉

请问这个类该如何调用呢?能不能给个调用的例子?谢谢  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2008-04-05 22:00 伍兴佳

已经很清楚了啊,表单调用,服务端程序都是通过表单调用,验证码生成器,使用此类需要将表单里的验证码输入框的name属性设为"verifycode" ,不知道你是什么意思。@子玉
  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~)[未登录] 2008-04-06 12:27 子玉

servlet如何调用这个类,还是直接写到servlet里?
前台的request如何传给VerifyCodeGenerator?对不起,我是新手上路  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2008-04-07 08:45 Jarod

java生成验证码见的多,看标题博主好像会用JS生成,期望能在下篇文章中分享一下  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2008-04-07 12:30 伍兴佳

JS中我只会生成纯数字和字符验证码,生成图像的我不会。  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2008-04-08 13:55 lmjq

谢谢分享,我用这个做了个例子,http://blog.csdn.net/lmjq/archive/2008/04/08/2259670.aspx
  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2008-12-05 11:51 jixinzheng@hotmail.com

部署这个servlet以后在浏览器中只看到一个图片的占位符,作者测过没有?  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~)[未登录] 2009-10-05 13:52 呆呆

这个验证码太不安全了。客户端可以先获得session 然后将这个值写到你哪个文本框里。验证码就没多太的意思了。  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2012-12-18 14:56 eee

eeee  回复  更多评论   

# re: 纯JAVA技术验证码生成器(服务器端servlet实现)(不是javascript哦~) 2014-06-25 20:42 dsadas

dasdasdad  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

导航

统计

公告

这是伍嗲的纯JAVA技术博客

常用链接

留言簿(1)

随笔档案

文章分类

相册

技术链接

搜索

最新评论

阅读排行榜

评论排行榜