java web驗證碼生成總結(包括servlet、jsp和struts2實現)

jopen 10年前發布 | 65K 次閱讀 驗證碼 驗證碼(Captcha)

一、使用純Servlet實現驗證碼

(1)在web.xml配置:

<servlet>   
    <servlet-name>image</servlet-name>   
    <servlet-class>org.test.web.AuthImage</servlet-class>   
</servlet>   

<servlet-mapping>   
    <servlet-name>image</servlet-name>   
 <url-pattern>/authImage</url-pattern>   
</servlet-mapping>  

(2)servlet源碼

public class AuthImage extends HttpServlet   
{   

    private static final String CONTENT_TYPE = "text/html; charset=gb2312";   
    //設置字母的大小,大小   
    private Font mFont = new Font("Times New Roman", Font.PLAIN, 17);   
    public void init() throws ServletException   
    {   
        super.init();   
    }   
    Color getRandColor(int fc,int bc)   
    {   
        Random random = new Random();   
        if(fc>255) fc=255;   
        if(bc>255) bc=255;   
        int r=fc+random.nextInt(bc-fc);   
        int g=fc+random.nextInt(bc-fc);   
        int b=fc+random.nextInt(bc-fc);   
        return new Color(r,g,b);   
    }   

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException   
    {   
        response.setHeader("Pragma","No-cache");   
        response.setHeader("Cache-Control","no-cache");   
        response.setDateHeader("Expires", 0);   
        //表明生成的響應是圖片   
        response.setContentType("image/jpeg");   

        int width=100, height=18;   
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);   

        Graphics g = image.getGraphics();   
        Random random = new Random();   
        g.setColor(getRandColor(200,250));   
        g.fillRect(1, 1, width-1, height-1);   
        g.setColor(new Color(102,102,102));   
        g.drawRect(0, 0, width-1, height-1);   
        g.setFont(mFont);   

        g.setColor(getRandColor(160,200));   

        //畫隨機線   
        for (int i=0;i<155;i++)   
        {   
            int x = random.nextInt(width - 1);   
            int y = random.nextInt(height - 1);   
            int xl = random.nextInt(6) + 1;   
            int yl = random.nextInt(12) + 1;   
            g.drawLine(x,y,x + xl,y + yl);   
        }   

        //從另一方向畫隨機線   
        for (int i = 0;i < 70;i++)   
        {   
            int x = random.nextInt(width - 1);   
            int y = random.nextInt(height - 1);   
            int xl = random.nextInt(12) + 1;   
            int yl = random.nextInt(6) + 1;   
            g.drawLine(x,y,x - xl,y - yl);   
        }   

        //生成隨機數,并將隨機數字轉換為字母   
        String sRand="";   
        for (int i=0;i<6;i++)   
        {   
            int itmp = random.nextInt(26) + 65;   
            char ctmp = (char)itmp;   
            sRand += String.valueOf(ctmp);   
            g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));   
            g.drawString(String.valueOf(ctmp),15*i+10,16);   
        }   

        HttpSession session = request.getSession(true);   
        session.setAttribute("rand",sRand);   
        g.dispose();   
        ImageIO.write(image, "JPEG", response.getOutputStream());   
    }   
    public void destroy()   
    {   
    }   
}  

(3)頁面顯示

<img src="authImage"/> 

 

 

 

二、使用純jsp實現驗證碼

<%@ page language="java" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" 
     contentType="image/jpeg" pageEncoding="UTF-8"%>


<%  //設置頁面不緩存
   response.setHeader("Pragma","No-cache");
   response.setHeader("Cahce-Control","no-cache");
   response.setDateHeader("Expires",0);
   //在內存中創建圖片
   int width=60,height=20;
   BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
   //獲取圖形上下文
   Graphics g= image.getGraphics();
   //生成隨機類
   Random random= new Random();
   //設置背景顏色
   g.setColor(new Color(160,200,100));
   g.fillRect(0,0,width,height);
   //設置字體
   g.setFont(new Font("Times New Roman",Font.PLAIN,18));
   //隨機產生50條干擾線,使圖形中的驗證碼不易被其他的程序探測到
    g.setColor(new Color(160,200,200));
   for(int i=0;i<50;i++)
   {
     int x=random.nextInt(width);
     int y=random.nextInt(height);
     int x1=random.nextInt(width);
     int y1=random.nextInt(height);
     g.drawLine(x,y,x+x1,y+y1);
   }
   //隨機產生驗證碼(6位數字)
   String sRand="";
   for(int i=0;i<6;i++)
   {
     String rand=String.valueOf(random.nextInt(10));
     sRand+=rand;
     //將驗證碼顯示到圖象
     g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
     g.drawString(rand,13*i+6,16);
   }
   session.setAttribute("rand",sRand);  //////將產生的驗證碼存儲到sesson中
   g.dispose();
   ImageIO.write(image,"JPEG",response.getOutputStream());
   out.clear(); //***********
   out=pageContext.pushBody();//**********
 %>

 

 

三、使用Struts2來實現驗證碼

(1)定義一個生成驗證碼的工具類

package com.cn.hospital.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.util.Random;   
import javax.imageio.ImageIO;   
import javax.imageio.stream.ImageOutputStream;   

public class RandomNumUtil {

    private ByteArrayInputStream image;//圖像    
    private String str;//驗證碼    

    private RandomNumUtil(){    
    init();//初始化屬性    
    }    
    /*   
    * 取得RandomNumUtil實例   
    */    
    public static RandomNumUtil Instance(){    
    return new RandomNumUtil();    
    }    
    /*   
    * 取得驗證碼圖片   
    */    
    public ByteArrayInputStream getImage(){    
    return this.image;    
    }    
    /*   
    * 取得圖片的驗證碼   
    */    
    public String getString(){    
    return this.str;    
    }    

    private void init() {    
    // 在內存中創建圖象    
    int width=85, height=20;    
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    
    // 獲取圖形上下文    
    Graphics g = image.getGraphics();    
    // 生成隨機類    
    Random random = new Random();    
    // 設定背景色    
    g.setColor(getRandColor(200,250));    
    g.fillRect(0, 0, width, height);    
    // 設定字體    
    g.setFont(new Font("Times New Roman",Font.PLAIN,18));    
    // 隨機產生155條干擾線,使圖象中的認證碼不易被其它程序探測到    
    g.setColor(getRandColor(160,200));    
    for (int i=0;i<155;i++)    
    {    
    int x = random.nextInt(width);    
    int y = random.nextInt(height);    
    int xl = random.nextInt(12);    
    int yl = random.nextInt(12);    
    g.drawLine(x,y,x+xl,y+yl);    
    }    
    // 取隨機產生的認證碼(6位數字)    
    String sRand="";    
    for (int i=0;i<6;i++){    
    String rand=String.valueOf(random.nextInt(10));    
    sRand+=rand;    
    // 將認證碼顯示到圖象中    
    g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));    
    // 調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成    
    g.drawString(rand,13*i+6,16);    
    }   
    //賦值驗證碼   
    this.str=sRand;    

    //圖象生效    
    g.dispose();    
    ByteArrayInputStream input=null;    
    ByteArrayOutputStream output = new ByteArrayOutputStream();    
    try{    
    ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);    
    ImageIO.write(image, "JPEG", imageOut);    
    imageOut.close();    
    input = new ByteArrayInputStream(output.toByteArray());    
    }catch(Exception e){    
    System.out.println("驗證碼圖片產生出現錯誤:"+e.toString());    
    }    

    this.image=input;/* 賦值圖像 */    
    }    
    /*   
    * 給定范圍獲得隨機顏色   
    */    
    private Color getRandColor(int fc,int bc){    
    Random random = new Random();    
    if(fc>255) fc=255;    
    if(bc>255) bc=255;    
    int r=fc+random.nextInt(bc-fc);    
    int g=fc+random.nextInt(bc-fc);    
    int b=fc+random.nextInt(bc-fc);    
    return new Color(r,g,b);    
    }   
}

(2)定義一個驗證碼輸出的action

package com.cn.hospital.action;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.cn.hospital.util.RandomCharUtil;
import com.cn.hospital.util.RandomNumUtil;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

@Controller("utilAction")
@Scope("prototype")
public class UtilAction extends ActionSupport{

    private static final long serialVersionUID = -7193209177116825032L;
    private ByteArrayInputStream inputStream; 

    private int width;   
    private int height;   
    private int fontSize;   
    private int codeLength; 
    private int disturbType;

    public String validNumGenerate() throws Exception{
        RandomNumUtil rdnu=RandomNumUtil.Instance();    
        this.setInputStream(rdnu.getImage());//取得帶有隨機字符串的圖片    
        ActionContext.getContext().getSession().put("random", rdnu.getString());//取得隨機字符串放入HttpSession    
        return SUCCESS;    
    } 


    public void setInputStream(ByteArrayInputStream inputStream) {    
        this.inputStream = inputStream;    
    }   

    public ByteArrayInputStream getInputStream() {    
        return inputStream;    
    }


}

(3)struts.xml配置

<!-- 產生隨機驗證碼 -->
        <action name="randNum" class="utilAction" method="validNumGenerate">      
           <result name="success" type="stream">      
                <param name="contentType">image/jpeg</param>      
                <param name="inputName">inputStream</param>      
           </result>   
        </action> 

 

 

四、小結

    對于java的web技術,歸根究底還是在服務器端執行的servlet.從上面的三種不同實現中,我們很容易察覺到他們存在一個共同點,那就是返回瀏覽器端的contentType。

    servlet:使用response.setContentType(" ");方法來實現

    jsp:在<@ page contentType=" ">中來實現

    struts2:通過配置<param name="contentType"> </param>來實現

 

至于驗證碼的產生其實比較簡單,在這里就不深究了。就此一點小感想,與同行共勉。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!