J2EE如何生成驗證碼圖片和點擊刷新驗證碼

驗證碼圖片生成步驟

  1. 建立BufferedImage對象。
  2. 獲取BufferedImage的畫筆,即調用getGraphics()方法獲取Graphics對象。
  3. 調用Graphics對象的setColor()方法和fillRect()方法設置圖片背景顏色。
  4. 調用Graphics對象的setColor()方法和drawLine()方法設置圖片干擾線。
  5. 調用BufferedImaged對象的setRGB()方法設置圖片的噪點。
  6. 調用Graphics對象的setColor()方法、setFont()方法和drawString()方法設置圖片驗證碼。

由於驗證碼的圖片的寬度和高度要根據網站的風格來肯定的,因此字體的大小須要根據圖片的寬度和高度來肯定,用到了小小的技巧。javascript

 

package util;

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

import javax.imageio.ImageIO;

public class Verification {
    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
    
    /**
     * 生成一個寬爲width, 高爲height, 驗證碼爲code的圖片
     * @param width 圖片的寬
     * @param height 圖片的高
     * @param code 驗證碼字符串
     * @return 返回圖片驗證碼
     */
    public static BufferedImage getImage(int width, int height, String code){
        return getImage(width, height, code, 20);
    }
    /**
     * 生成一個寬爲width, 高爲height, 驗證碼爲code的圖片,圖片中干擾線的條數爲lineCnt
     * @param width 圖片的寬
     * @param height 圖片的高
     * @param code 驗證碼字符串
     * @param lineCnt 干擾線的條數,建議爲10條左右,可根據結果適當調整
     * @return 返回圖片驗證碼
     */
    public static BufferedImage getImage(int width, int height, String code, int lineCnt){
        return createImage(width, height, code, lineCnt, 0.01);
    }
    /**
     * 生成一個寬爲width, 高爲height, 驗證碼爲code的圖片,圖片中干擾線的條數爲lineCnt
     * 噪聲比爲noiseRate,即圖片中噪音像素點的百分比
     * @param width 圖片的寬
     * @param height 圖片的高
     * @param code 驗證碼字符串
     * @param lineCnt 干擾線的條數,建議爲10條左右,可根據結果適當調整
     * @param noiseRate 圖片中噪音像素點佔總像素的百分比
     * @return 返回圖片驗證碼
     */
    public static BufferedImage getImage(int width, int height, String code, int lineCnt, double noiseRate){
        return createImage(width, height, code, lineCnt, noiseRate);
    }
    
    /**
     * 
     * 生成一個寬爲width, 高爲height, 驗證碼爲code的圖片,圖片中干擾線的條數爲lineCnt
     * 噪聲比爲noiseRate,即圖片中噪音像素點的百分比
     * @param width 圖片的寬
     * @param height 圖片的高
     * @param code 驗證碼字符串
     * @param lineCnt 干擾線的條數,建議爲10條左右,可根據結果適當調整
     * @param noiseRate 圖片中噪音像素點佔總像素的百分比
     * @return 返回圖片驗證碼
     */
    private static BufferedImage createImage(int width, int height, String code, int lineCnt, double noiseRate){
        int fontWidth = ((int)(width * 0.8)) / code.length();
        int fontHeight = (int)(height * 0.7);
        //爲了在任意的width和height下都能生成良好的驗證碼,
        //字體的大小爲fontWdith何fontHeight中的小者,
        int fontSize = Math.min(fontWidth, fontHeight);
        //drawString時要用到
        int paddingX = (int) (width * 0.1);
        int paddingY = height - (height - fontSize) / 2;
        
        //建立圖像
        BufferedImage buffimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //得到畫筆
        Graphics g = buffimg.getGraphics();
        //設置畫筆的顏色
        g.setColor(getRandColor(200, 255));
        //而後填充一個矩形,即設置背景色
        g.fillRect(0, 0, width, height);
        
        // 設置干擾線
        for (int i = 0; i < lineCnt; i++) {
                //隨機獲取干擾線的起點和終點
            int xs = (int)(Math.random() * width);
            int ys = (int)(Math.random() * height);
            int xe = (int)(Math.random() * width);
            int ye = (int)(Math.random() * height);
            g.setColor(getRandColor(1, 255));
            g.drawLine(xs, ys, xe, ye);
        }
        // 添加噪點
        int area = (int) (noiseRate * width * height);
        for(int i=0; i<area; ++i){
                int x = (int)(Math.random() * width);
                int y = (int)(Math.random() * height);
                buffimg.setRGB(x, y, (int)(Math.random() * 255));
        }
        //設置字體
        Font font = new Font("Ravie", Font.PLAIN, fontSize);
        g.setFont(font);
        
        for(int i=0; i<code.length(); ++i){
                String ch = code.substring(i, i+1);
                g.setColor(getRandColor(1, 199));
                g.drawString(ch, paddingX + fontWidth * i, paddingY);
        }
        return buffimg;
        
    }
    /**
     * 獲取隨機的顏色,r,g,b的取值在L到R之間
     * @param L 左區間
     * @param R 右區間
     * @return 返回隨機顏色值
     */
    private static Color getRandColor(int L, int R){
        if(L > 255)
            L = 255;
        if(R > 255)
            R = 255;
        if(L < 0)
            L = 0;
        if(R < 0)
            R = 0;
        int interval = R - L; 
        int r = L + (int)(Math.random() * interval);
        int g = L + (int)(Math.random() * interval);
        int b = L + (int)(Math.random() * interval);
        return new Color(r, g, b);
    }

    /**
     * 隨機生成若干個由大小寫字母和數字組成的字符串
     * @param len 隨機生成len個字符
     * @return 返回隨機生成的若干個由大小寫字母和數字組成的字符串
     */
    public static String getRandCode(int len){
        String code = "";
        for(int i=0; i<len; ++i){
            int index = (int)(Math.random() * ALPHABET.length());
            code = code + ALPHABET.charAt(index);
        }
        return code;
    }
    /**
     * 將圖片轉爲byte數組
     * @param image 圖片
     * @return 返回byte數組
     * @throws IOException
     */
    public static byte[] getByteArray(BufferedImage image) throws IOException{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        return baos.toByteArray();
        //ByteArrayOutputStream 不須要close
        
    }
}
 

 

 

使用驗證碼圖片

在verificationCode.java這個servlet中調用上面的類生成驗證碼圖片,而後將圖片返回給客戶端。html

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        //隨機生成字符串,並寫入session
        String code = Verification.getRandCode(4);
        session.setAttribute("verification", code);
        BufferedImage image = util.Verification.getImage(100,30, code, 5);
        response.setContentType("image/png");
        
        OutputStream out =  response.getOutputStream();
        out.write(util.Verification.getByteArray(image));
        out.flush();
        out.close();
        
    }

 

在index.jsp中設置驗證碼,用戶點擊驗證碼時,調用js代碼請求服務器獲得新的驗證碼。由於上面的那個生成驗證碼的servlet會被瀏覽器緩存,因此js代碼中須要給該servlet一個隨機的參數,這樣瀏覽器就會向服務器發請求獲得新的驗證碼,而不是去緩存中讀取。java

<%@page import="util.Verification"%>
<%@ 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>Insert title here</title>

<script type="text/javascript">
        function refreshcode(){
            document.getElementById("verification").src= "/verificationCode/verificationCode?hehe="+Math.random();
        }
    </script>
</head>
<body>
    
    <form action="<%=request.getContextPath()+"/checkVerification" %>" method="post">
        驗證碼:<input type="text" name="submitVerification">
        <img id="verification" alt="" title="看不清點擊刷新驗證碼" src="<%=request.getContextPath()+"/verificationCode" %>"
        onclick="refreshcode()"><br>
        <input type="submit" name="submit" value="提交">
    </form>
    
</body>
</html>

 

 最後是在checkVerification.java這個servlet中判斷用戶輸入的驗證碼是否正確,爲了方便用戶,驗證碼通常都設置成大小寫不敏感,因此要先轉化爲小寫字母再比對。數組

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String verification = (String)session.getAttribute("verification");
        String submitVerification = request.getParameter("submitVerification");
        PrintWriter out = response.getWriter();
        if(verification!=null && submitVerification!=null){
            if(verification.toLowerCase().equals(submitVerification.toLowerCase())){
                out.println("yes!!!");
            }
            else{
                out.println("no!!!");
            }
            
        }
        else{
            out.println("no!!!");
        }
        session.removeAttribute("verification");//防止用戶重複提交表單

    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

 

 

 

最後運行的效果圖以下瀏覽器

 

該文章在個人我的博客地址是:http://www.alphaway.org/post-464.html緩存

相關文章
相關標籤/搜索