`
cnlsh
  • 浏览: 2174 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

servlet生产唯一图片验证码

阅读更多
参考了几篇文章,写了个用servlet生产唯一验证码(改造了原作者代码,在此致谢,后附链接)。附件是可直接使用的工程。明天试用一个开源项目,可以比较方便的生成各种风格的验证码,甚至还有声音,比较有意思。第一次记录自己的学习,以后争取每天写一点。
===================================================
package com.stone.study.validate;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

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;

public class ImgValidateServlet2 extends HttpServlet {
	private static int WIDTH = 90;
    private static int HEIGHT = 20;
    private static int LENGTH = 6;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 HttpSession session = request.getSession();

         response.setContentType("image/jpeg");

         ServletOutputStream sos = response.getOutputStream();

         //设置浏览器不要缓存此图片
         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 g = image.getGraphics();

         //产生随机的认证码
         char [] rands = generateCheckCode();

         //产生图像
         drawBackground(g);

         drawRands(g,rands);

         //结束图像的绘制过程,完成图像
         g.dispose();

         //将图像输出到客户端
         ByteArrayOutputStream bos = new ByteArrayOutputStream();

         ImageIO.write(image, "JPEG", bos);

         byte [] buf = bos.toByteArray();

         response.setContentLength(buf.length);

         //下面的语句也可写成:bos.writeTo(sos);
         sos.write(buf);
         bos.close();
         sos.close();

         //将当前验证码存入到Session或者数据库中,下一个表单处理中验证客户端提交的验证码是否正确
         session.setAttribute("check_code",new String(rands));
	}

	private static char [] generateCheckCode()
    {
       //定义验证码的字符表
       String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

       char [] rands = new char[LENGTH];
       for(int i=0; i<LENGTH; i++)

       {
          int rand = (int)(Math.random() * 36);
          rands[i] = chars.charAt(rand);
       }

       return rands;
    }
	
	   private void drawRands(Graphics g , char [] rands) 
       {
          g.setColor(Color.BLACK);
          g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));

          //在不同的高度上输出验证码的每个字符         
          g.drawString("" + rands[0],1,17);
          g.drawString("" + rands[1],16,15);
          g.drawString("" + rands[2],31,18);
          g.drawString("" + rands[3],46,16);
          g.drawString("" + rands[4],61,14);
          g.drawString("" + rands[5],76,19);

          System.out.println(rands);
       }

       private void drawBackground(Graphics g)

       {
           //画背景
          g.setColor(new Color(0xDCDCDC));
          g.fillRect(0, 0, WIDTH, HEIGHT);

          //随机产生120个干扰点
          for(int i=0; i<120; i++)

          {
             int x = (int)(Math.random() * WIDTH);

             int y = (int)(Math.random() * HEIGHT);

             int red = (int)(Math.random() * 255);

             int green = (int)(Math.random() * 255);

             int blue = (int)(Math.random() * 255);

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

             g.drawOval(x,y,1,0);

          }
          
          //加两条干扰线
          g.drawLine(0, 5, 90, 5);
          g.drawLine(0, 15, 90, 15);

       }

       public static void main(String args[]) {
    	   char[] chars = generateCheckCode();

    	   System.out.println(chars);
       }
}



代码出处:《深入体验Java Web开发内幕——核心基础》
分享到:
评论
13 楼 qqj_1979 2009-07-24  
验证码这块是比较通用不需乱改的代码,很多做web的都会用到

建议大家贴一下你们自己认为比较好的实现。
12 楼 kc_ren 2009-07-07  
很不错,已经用上了
11 楼 bohemia 2009-02-17  
qjmouse 写道
bohemia 写道
ImageIO.write(image, "JPEG", bos);  

这句效率极低...

给你个好的方法,参考下:
try{
    com.sun.jimi.core.Jimi.putImage("image/jpeg", image4, out);
}catch(Exception e){
    e.printStackTrace();
}
速度快,需要使用Sun提供的包,独立;
下载地址,不知道现在是否换有效:http://java.sun.com/products/jimi/

Jimi是一个操作图片的类库,它的原函数是image I/O。Jimi是以前Activated Intelligence的产品。该包sun是为依赖于Jimi的程序开发人员或运行在1.1.x版本Java平台的需要image I/O功能的应用程序提供的。Jimi支持的文件类型包括有:GIF, JPEG, TIFF, PNG, PICT, Photoshop, BMP, Targa, ICO, CUR, Sunraster, XBM, XPM, and PCX。不过并不支持个别类型的所有属性。
sun网站对于jimi的介绍,好像没讲到有jimi性能会高哦,好像是为低版本Java平台提供图片处理能力。而且接着就说到"For developers interested in image I/O on the Java 2 Platform the Java Image I/O API has been available since Java 2 version 1.4.0. "。
不过具体是不是如你所说没怎用过就不太清楚,还望高手再详说。

测试过,相差大概5倍左右;
ImageIO的性能是低一些的. 在Unix和Win下都测试过. 是jmi的性能高很多.

可以实际测试下,再决定用哪个. 满足需求才是主要的.
10 楼 xuhbiao 2008-12-25  
学习了~~!
9 楼 qjmouse 2008-12-19  
bohemia 写道
ImageIO.write(image, "JPEG", bos);  

这句效率极低...

给你个好的方法,参考下:
try{
    com.sun.jimi.core.Jimi.putImage("image/jpeg", image4, out);
}catch(Exception e){
    e.printStackTrace();
}
速度快,需要使用Sun提供的包,独立;
下载地址,不知道现在是否换有效:http://java.sun.com/products/jimi/

Jimi是一个操作图片的类库,它的原函数是image I/O。Jimi是以前Activated Intelligence的产品。该包sun是为依赖于Jimi的程序开发人员或运行在1.1.x版本Java平台的需要image I/O功能的应用程序提供的。Jimi支持的文件类型包括有:GIF, JPEG, TIFF, PNG, PICT, Photoshop, BMP, Targa, ICO, CUR, Sunraster, XBM, XPM, and PCX。不过并不支持个别类型的所有属性。
sun网站对于jimi的介绍,好像没讲到有jimi性能会高哦,好像是为低版本Java平台提供图片处理能力。而且接着就说到"For developers interested in image I/O on the Java 2 Platform the Java Image I/O API has been available since Java 2 version 1.4.0. "。
不过具体是不是如你所说没怎用过就不太清楚,还望高手再详说。
8 楼 sy19861216 2008-12-18  
现在的验证应该都要应用Ajax实现。。
J2ee基本学完一遍,看到这些代码,虽然掌握理论明白怎么回事,不过很多awt类都不熟悉。如果叫我上手就写估计要折腾很久。新手跟有经验的差别吧
7 楼 ray_linn 2008-12-02  
Jcaptcha..
6 楼 dust_dn 2008-12-02  
lz是学生,呵呵。。
5 楼 cnlsh 2008-11-18  
第一次发,且几乎是转发,得到这么多帮助,谢谢上面这些同学
4 楼 hateeyes 2008-11-12  
不错,学习。。。
3 楼 sdh5724 2008-11-12  
ImageIO支持NATIVE的IO的, 性能很不错了。
我们对JAI/IMAGEIO使用的比较多。 如果把NATIVE开启, 还能支持更多的图形格式。

JAI/IMAGEIO的成熟度似乎不是很好, 很多API的设计不合理, BUG也不少, 通用图形处理还是不错的。

如果想用更好的, 可以考虑JMAGIC了, 不过需要额外的NATIVE CODE安装。 换OS还是很恼火的。
2 楼 bohemia 2008-11-11  
ImageIO.write(image, "JPEG", bos);  

这句效率极低...

给你个好的方法,参考下:
try{
    com.sun.jimi.core.Jimi.putImage("image/jpeg", image4, out);
}catch(Exception e){
    e.printStackTrace();
}
速度快,需要使用Sun提供的包,独立;
下载地址,不知道现在是否换有效:http://java.sun.com/products/jimi/
1 楼 sdh5724 2008-11-11  
ImageIO.write(image, "JPEG", bos);   这么写是有BUG的, 可能导致你系统的流没有办法关闭。 你可以使用压力测试作作看。 虽然这样的代码很漂亮。 这是JAI的一个BUG导致的。 很恶心。

从使用方便角度, 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ      0/o 1/L 应该删除掉一个。

相关推荐

    登陆验证+servlet动态生成图片验证码

    在Servlet中生成图片验证码,首先需要创建一个Servlet类,该类将负责生成随机字符串并将其转化为图像。以下是一些关键步骤: 1. **生成随机字符串**:使用`java.util.Random`和`char[]`数组来创建一个指定长度的...

    servlet实现的图片验证码

    本教程将详细介绍如何使用Servlet技术来实现一个基本的图片验证码功能。Servlet是Java服务器端编程的核心技术之一,它可以接收和响应HTTP请求,非常适合构建动态Web应用程序。 首先,我们需要理解验证码的基本原理...

    Java servlet 自动生成 图片验证码 生成 Java源码

    Java servlet 自动生成 图片验证码 生成 Java源码

    Servlet生成图片验证码

    在这个场景中,我们使用Servlet来生成图片验证码,这是一种防止恶意自动化程序(如机器人)进行非法操作的安全机制。验证码通常是一串随机生成的字符,以图像形式显示,用户需要在输入框中正确输入才能完成验证。 ...

    使用Servlet生成图片验证码

    本文将深入讲解如何使用Servlet来创建图片验证码,确保用户交互的安全性。验证码的主要目的是防止自动化程序(如机器人)对网站进行恶意操作,例如注册大量虚假账户或进行垃圾信息提交。 首先,我们需要了解Servlet...

    servlet生成四位数验证码图片

    在servlet中动态生成验证码图片,可被JSP或servlet引用,每次刷新都会改变验证码

    servlet生成验证码图片

    `servlet`生成验证码图片是通过服务器端动态创建一个包含随机字符的图像,用户需要输入图像中显示的文字或数字来验证其身份。以下将详细解释这个过程及其相关知识点: 1. **Servlet**:Servlet是Java中用于扩展...

    JSP中利用Servlet生成验证码图片

    ### JSP中利用Servlet生成验证码图片 在Web应用开发中,验证码被广泛应用于用户登录、表单提交等场景,以防止自动化的恶意攻击。本文将详细介绍如何在Java Server Pages (JSP) 和 Servlet 技术的基础上,实现一个...

    servlet+jsp实现验证码demo

    servlet+jsp实现验证码 具体步骤: 生成图片所要实现的类 1、定义BufferedImage对象 2、获得Graphics对象 3、使用Random生成随机验证码信息 4、使用Graphics绘制图片 5、记录验证信息到session 6、使用ImageIO生成...

    jsp,servlet,验证码,验证码点击更换

    3. **Servlet处理请求**:Servlet接收到更换验证码的请求后,生成新的验证码字符串,更新服务器端的验证码状态,并且创建新的验证码图像。 4. **返回新验证码**:Servlet将新生成的验证码图像作为响应返回,可以以...

    jsp+servlet编写的验证码程序

    jsp+servlet编写的验证码程序 jsp+servlet编写的验证码程序是一种基于Java EE的验证码生成程序,使用jsp和servlet技术来生成验证码。在本节中,我们将详elerate这个程序的结构和实现细节。 一、项目结构 项目结构...

    验证码校验servlet实现

    2. **显示验证码**:当用户请求验证码时,Servlet会生成验证码图片,并通过HTTP响应发送给浏览器。在HTML页面中,可以使用`&lt;img&gt;`标签引用这个Servlet,以显示验证码图片。 3. **用户输入**:用户在看到验证码后,...

    Servlet_验证码图片

    Servlet下实现的中英文验证码图片,供大家学习交流之用,附带一张JSP测试页面.

    Servlet动态验证码的生成-带数字和字母

    本篇文章将深入探讨如何在Servlet中生成一种包含数字和字母的动态验证码。 验证码的主要目的是验证用户是人而不是机器,通过让用户提供显示的一串随机字符(数字和字母混合)来达到这一目的。在Servlet中实现动态...

    利用servlet动态生成验证码

    本教程主要讲解如何利用Servlet来实现动态生成验证码的功能,这对于防止机器人或恶意自动化程序在网站上进行非法操作至关重要。验证码通常由一串随机字符组成,用户需要正确输入才能完成特定操作,如注册、登录或...

    jsp+servlet实现发送短信验证码(实现简单手机登录)

    【JSP + Servlet 实现发送短信验证码:构建安全的手机登录系统】 在现代Web开发中,短信验证码已经成为一种常见的安全措施,用于验证用户的身份,防止恶意登录和其他欺诈行为。本项目利用Java Web技术栈,包括JSP...

    java用servlet实现登陆验证码

    Java使用Servlet实现登录验证码涉及到的是Web开发中的安全性与用户体验部分。验证码是一种常用的安全机制,用于防止自动化的机器人或恶意程序进行非法操作,如批量注册、恶意登录等。在这个例子中,我们将探讨两种...

    Servlet实现验证码

    本文档详细摘录了用servlet实现java中验证码的实现代码。

    生成验证码(带详细注释、Servlet已获取生成的验证码和输入的验证码)

    - **Servlet验证**:在用户提交表单时,Servlet会收到用户输入的验证码,与服务器保存的原始验证码进行比较。如果一致,则验证成功;否则,提示用户重新输入。 - **安全性考虑**:为了安全,验证码的有效期通常很...

Global site tag (gtag.js) - Google Analytics