Java 验证码生成工具(简单实现)

在使用Java开发Web应用程序特别是时,常常要用到验证码,特别是在注册新用户、登陆时,大量地使用到验证码;javascript

好的验证码能够有效的防止黑客使用机器人恶意登陆,总之对于系统的安全是有很大影响的,如下为本人在平时开发项目的过程当中总结出来的一个简单的验证码生成工具,原理很简单,只有一个类;html

 

下面进入正题:java

step1  在MyEclipse中新建一个web项目,在这里取名为ImageUtil,并在src目录下新建一个类 ImageUtil.javajquery

image

 

step2  ImageUtil.java代码以下:web

复制代码
package util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 简单验证码生成工具
 * ImageUtil, 用于生成验证码
 * createImage方法返回一个Map类型,Map 的key是所生产的验证码的字符串,
 * Map的value是所生产的BufferImage类型的验证码;
 * getInputStream方法将 BufferImage转成InputStream类型;
 * @author CayZlh
 * @date 2013-11-26
 */
public class ImageUtil {
    private static final char[] chars = {'0','1','2','3','4','5','6','7','8','9',
        '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','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'};
    private static final int SIZE = 4;            //字符数
    private static final int LINES = 12;        //干扰线数量
    private static final int WIDTH = 100;        //生成的验证码图片的宽度
    private static final int HEIGHT = 60;        //生成的验证码图片的长度
    private static final int FONT_SIZE = 35;    //字体大小

    public static Map<String, BufferedImage> createImage(){
        //用户保存字符串
        StringBuffer sb = new StringBuffer();
        //BufferImage类型的验证码
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        //得到画笔 
        Graphics g = image.getGraphics();
        g.setColor(Color.LIGHT_GRAY);    //设置背景色
        g.fillRect(0, 0, WIDTH, HEIGHT);//将背景色填充到图片中
        Random ran = new Random();    //得到一个Random对象
        
        //画字符
        for(int i=1; i<=SIZE; i++){
            int r = ran.nextInt(chars.length);    //获得一个随机的下标, chars 是保存着若干字符的char字符
            g.setColor(getRandomColor());        //获得一个随机的颜色
            g.setFont(new Font(null, Font.BOLD+Font.ITALIC, FONT_SIZE));    //设置字体大小
            g.drawString(chars[r]+"", (i-1)*WIDTH/SIZE, (int)(HEIGHT*0.7));    //画字符
            sb.append(chars[r]);
        }
        
        //画干扰线
        for(int i=1; i<=LINES; i++){
            g.setColor(getRandomColor());    //一样,干扰线也是用随机的颜色
            g.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), 
                    ran.nextInt(WIDTH), ran.nextInt(HEIGHT));//随机设置干扰线的方向
        }
        
        //将图片中的字符串保存为Map对象的key,BufferedImage保存为value
        Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();    
        map.put(sb.toString(), image);
        return map;
    }

    /**
     * 得到一个随机的颜色 返回 Color对象
     * @return
     */
    private static Color getRandomColor() {
        Random ran = new Random();
        Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256)); 
        return color;
    }

    /**
     * 将 BufferImage转成InputStream类型
     * @param image
     * @return
     * @throws IOException
     */
    public static InputStream getInputStream(BufferedImage image) throws IOException{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
        encoder.encode(image);
        byte[] imageBts = bos.toByteArray();
        InputStream in = new ByteArrayInputStream(imageBts);
        return in;
    }
}
复制代码

到此为止,ImageUtil工具类算是写完了。apache

 

接下来,就是去测试一下这个工具类的可用性了, 这部分我以Struts2为例展现一下效果,导入Struts2开发的jar包,新建Action类:浏览器

image

 

ImageDemoAction.java代码以下:安全

复制代码
package action;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import util.ImageUtil;

public class ImageDemoAction {
    
    //stream result只能输出InputStream类型
    private InputStream imageStream;

    public InputStream getImageStream() {
        return imageStream;
    }

    public void setImageStream(InputStream imageStream) {
        this.imageStream = imageStream;
    }
    
    public String execute() throws IOException{
        //生成验证码
        Map<String, BufferedImage> map = ImageUtil.createImage();
        String key = map.keySet().iterator().next();
        BufferedImage image = map.get(key);
        imageStream = ImageUtil.getInputStream(image);
        return "success";
    }
}
复制代码

step3  添加Struts配置文件:服务器

复制代码
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">

<struts>
  <package name="demo" extends="struts-default" namespace="/demo">
      <action name="image" class="action.ImageDemoAction">
            <!-- 
                inputName是固定写法, 目的是给这种类型的Result对象的inputName属性赋值.
                imageStream是Action里的输出属性名, 这个输出属性是InputStream类型的
             -->
            <result type="stream">
                <param name="inputName">imageStream</param>
            </result>
        </action>
  </package>

</struts>
复制代码

该注意的地方在注释部分也有给出app

 

  step4  配置web.xml:

    web.xml的配置比较简单,就配置一个过滤器就行

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <filter>
    <filter-name>Struts2</filter-name>
    <filter-class>
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
  </filter>
  <filter-mapping>
    <filter-name>Struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
复制代码

 

  step5  添加demo.jsp页面(须要引入jquery文件, 这里使用 jquery-1.4.3.js 版本,我的以为这个版本是最好用的):

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>demo</title>
<script type="text/javascript" src="js/jquery-1.4.3.js"></script>
        <script type="text/javascript">
            $(function(){
                //为图片绑定单击事件
                $('#imageCode').click(function(){
                    //设置src属性为action的参数为当前时间,保证验证码点击以后能够变换
                    $(this).attr('src', 'demo/image.action?dt=' + new Date().getTime());
                });
            });
        </script> 
</head>
<body>
    <img src="demo/image.action" width="70" height="30"
                     alt="验证码" title="点击更换" id="imageCode" style="cursor: pointer;" />
</body>
</html>
复制代码

 

  step6  部署并启动服务器,在浏览器查看效果:

  image

 

点击图片,能够更换图片。

 

image

 

项目总体结构以下:

image

 

这个工具能够直接应用到各类web项目中,若是不是用Struts,也可使用servlet转发到页面中。

    源代码下载地址 http://files.cnblogs.com/cayzlh/ImageUtil.zip

有表达和技术不足的地方,欢迎指正。。。

相关文章
相关标签/搜索