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

有表達和技術不足的地方,歡迎指正。。。

相關文章
相關標籤/搜索