天天看點

jsp頁面擷取java生成的圖檔驗證碼

【原文連結】https://blog.csdn.net/mr_xiyue/article/details/51016667

功能實作:實作自動生成圖檔驗證碼,點選驗證碼能夠更換驗證碼

valida.jsp

<div class="valida">
	<input type="text" name="valida" id="valida" οnkeydοwn="doEnter();">
	<span><img src="${ctx}/code" id="imgValida" οnclick="this.src='${ctx}/code?a='+Math.random()" class="imgValida">
	</span>	
</div>
           

VerifyCodeServlet.java

import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.Color;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;

/**
 * 向浏覽器輸出驗證碼
 *
 */
@WebServlet("/code")
public class VerifyCodeServlet extends HttpServlet {

	/**
	 * Constructor of the object.
	 */
	public VerifyCodeServlet() {
		super();
	}

	public void destroy() {
		super.destroy(); 
	}

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		
		        //設定浏覽器不緩存本頁				
		        response.setDateHeader("Expires", 0);   
		      	response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");  
		        response.addHeader("Cache-Control", "post-check=0, pre-check=0");   	       
		        response.setHeader("Pragma", "no-cache");   

				//生成驗證碼,寫入使用者session
				String verifyCode=VerifyCode.generateTextCode(VerifyCode.TYPE_NUM_UPPER,4,"0oOilJI1");
				request.getSession().setAttribute(VerifyCode.VERIFY_TYPE_COMMENT,verifyCode);
				System.out.println("verifyCode="+verifyCode);
				
				//輸出驗證碼給用戶端
				response.setContentType("image/jpeg");
				/*
				    textCode 文本驗證碼
					width 圖檔寬度
					height 圖檔高度
					interLine 圖檔中幹擾線的條數
					randomLocation 每個字元的高低位置是否随機
					backColor 圖檔顔色,若為null,則采用随機顔色
					foreColor 字型顔色,若為null,則采用随機顔色
					lineColor 幹擾線顔色,若為null,則采用随機顔色
				*/
				BufferedImage bim=VerifyCode.generateImageCode(verifyCode, 70, 22, 15,true,Color.WHITE,Color.BLACK,null);
				ServletOutputStream out=response.getOutputStream();
				ImageIO.write(bim, "JPEG",out);	
				try{
					out.flush();
				}finally{
					out.close();
				}
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
                 doGet(request,response);
 }

	public void init() throws ServletException {
		// Put your code here
	}

}

           

VerifyCode.java

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 驗證碼生成器類,可生成數字、大寫、小寫字母及三者混合類型的驗證碼。
 * 支援自定義驗證碼字元數量;
 * 支援自定義驗證碼圖檔的大小;
 * 支援自定義需排除的特殊字元;
 * 支援自定義幹擾線的數量;
 * 支援自定義驗證碼圖文顔色
 */
public class VerifyCode {
	
	//驗證碼類型
	public static final String VERIFY_TYPE_COMMENT="VERIFY_TYPE_COMMENT";
	
	/**
	 * 驗證碼類型為僅數字 0~9
	 */
	public static final int TYPE_NUM_ONLY=0;

	/**
	 * 驗證碼類型為僅字母,即大寫、小寫字母混合
	 */
	public static final int TYPE_LETTER_ONLY=1;
	
	/**
	 * 驗證碼類型為數字、大寫字母、小寫字母混合
	 */
	public static final int TYPE_ALL_MIXED=2;

	/**
	 * 驗證碼類型為數字、大寫字母混合
	 */
	public static final int TYPE_NUM_UPPER=3;		
	
	/**
	 * 驗證碼類型為數字、小寫字母混合
	 */
	public static final int TYPE_NUM_LOWER=4;	
	
	/**
	 * 驗證碼類型為僅大寫字母
	 */
	public static final int TYPE_UPPER_ONLY=5;
	
	/**
	 * 驗證碼類型為僅小寫字母
	 */
	public static final int TYPE_LOWER_ONLY=6;
	
		
	private VerifyCode(){}

	/**
	 * 生成驗證碼字元串
	 * @param type 驗證碼類型,參見本類的靜态屬性
	 * @param length 驗證碼長度,大于0的整數
	 * @param exChars 需排除的特殊字元(僅對數字、字母混合型驗證碼有效,無需排除則為null)
	 * @return 驗證碼字元串
	 */
	public static String generateTextCode(int type,int length,String exChars){
		
		if(length<=0) return "";
		
		StringBuffer code=new StringBuffer();
		int i=0;
		Random r=new Random();
		
		switch(type)
		{
		
		//僅數字
		case TYPE_NUM_ONLY:
			while(i<length){
	            int t=r.nextInt(10);
				if(exChars==null||exChars.indexOf(t+"")<0){//排除特殊字元
					code.append(t);
					i++;
				}
			}
			break;
			
	    //僅字母(即大寫字母、小寫字母混合)
		case TYPE_LETTER_ONLY:
			while(i<length){
				int t=r.nextInt(123);
				if((t>=97||(t>=65&&t<=90))&&(exChars==null||exChars.indexOf((char)t)<0)){
					code.append((char)t);
					i++;	
				}
			}
			break;
		
		//數字、大寫字母、小寫字母混合
		case TYPE_ALL_MIXED:
			while(i<length){
				int t=r.nextInt(123);
				if((t>=97||(t>=65&&t<=90)||(t>=48&&t<=57))&&(exChars==null||exChars.indexOf((char)t)<0)){
					code.append((char)t);
					i++;
				}
			}
			break;	
			
		//數字、大寫字母混合
		case TYPE_NUM_UPPER:
			while(i<length){
				int t=r.nextInt(91);
				if((t>=65||(t>=48&&t<=57))&&(exChars==null||exChars.indexOf((char)t)<0)){
					code.append((char)t);
					i++;
				}
			}
			break;		
			
		//數字、小寫字母混合
		case TYPE_NUM_LOWER:
			while(i<length){
				int t=r.nextInt(123);
				if((t>=97||(t>=48&&t<=57))&&(exChars==null||exChars.indexOf((char)t)<0)){
					code.append((char)t);
					i++;
				}
			}
			break;		
			
		//僅大寫字母
		case TYPE_UPPER_ONLY:
			while(i<length){
				int t=r.nextInt(91);
				if((t>=65)&&(exChars==null||exChars.indexOf((char)t)<0)){
					code.append((char)t);
					i++;
				}
			}
			break;				
			
		//僅小寫字母
		case TYPE_LOWER_ONLY:
			while(i<length){
				int t=r.nextInt(123);
				if((t>=97)&&(exChars==null||exChars.indexOf((char)t)<0)){
					code.append((char)t);
					i++;
				}
			}
			break;				
		
		}
		
		return code.toString();
	}

	
	/**
	 * 已有驗證碼,生成驗證碼圖檔
	 * @param textCode 文本驗證碼
	 * @param width 圖檔寬度
	 * @param height 圖檔高度
	 * @param interLine 圖檔中幹擾線的條數
	 * @param randomLocation 每個字元的高低位置是否随機
	 * @param backColor 圖檔顔色,若為null,則采用随機顔色
	 * @param foreColor 字型顔色,若為null,則采用随機顔色
	 * @param lineColor 幹擾線顔色,若為null,則采用随機顔色
	 * @return 圖檔緩存對象
	 */
	public static BufferedImage generateImageCode(String textCode,int width,int height,int interLine,boolean randomLocation,Color backColor,Color foreColor,Color lineColor){
		
		
		BufferedImage bim=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		Graphics g=bim.getGraphics();
		//畫背景圖
		g.setColor(backColor==null?getRandomColor():backColor);
		g.fillRect(0,0,width,height);
		
		//畫幹擾線
		Random r=new Random();
		if(interLine>0){
	
			int x=0,y=0,x1=width,y1=0;
			for(int i=0;i<interLine;i++){
				g.setColor(lineColor==null?getRandomColor():lineColor);
				y=r.nextInt(height);
				y1=r.nextInt(height);
	
				g.drawLine(x,y,x1,y1);
			}
		}
		
		//字型大小為圖檔高度的80%
		int fsize=(int)(height*0.8);
		int fx=height-fsize;
		int fy=fsize;
		
		g.setFont(new Font("Times New Roman", Font.BOLD, 20));
		
		//寫驗證碼字元
		for(int i=0;i<textCode.length();i++){
			fy=randomLocation?(int)((Math.random()*0.3+0.6)*height):fy;//每個字元高低是否随機
			g.setColor(foreColor==null?getRandomColor():foreColor);
			g.drawString(textCode.charAt(i)+"",fx,fy);
			fx+=fsize*0.9;
		}
		
		g.dispose();
		
		return bim;
	}

	
	
	/**
	 * 直接生成圖檔驗證碼
	 * @param type 驗證碼類型,參見本類的靜态屬性
	 * @param length 驗證碼字元長度,大于0的整數
	 * @param exChars 需排除的特殊字元
	 * @param width 圖檔寬度
	 * @param height 圖檔高度
	 * @param interLine 圖檔中幹擾線的條數
	 * @param randomLocation 每個字元的高低位置是否随機
	 * @param backColor 圖檔顔色,若為null,則采用随機顔色
	 * @param foreColor 字型顔色,若為null,則采用随機顔色
	 * @param lineColor 幹擾線顔色,若為null,則采用随機顔色
	 * @return 圖檔緩存對象
	 */
	public static BufferedImage generateImageCode(int type,int length,String exChars,int width,int height,int interLine,boolean randomLocation,Color backColor,Color foreColor,Color lineColor){
		
		String textCode=generateTextCode(type,length,exChars);
		BufferedImage bim=generateImageCode(textCode,width,height,interLine,randomLocation,backColor,foreColor,lineColor);
		
		return bim;
	}
	
	/**
	 * 産生随機顔色
	 * @return
	 */
	private static Color getRandomColor(){
		Random r=new Random();
		Color c=new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255));
		return c;
	}

}

           

效果圖

jsp頁面擷取java生成的圖檔驗證碼