Java图片验证码Servlet

来源:互联网 发布:imo软件 编辑:程序博客网 时间:2024/05/29 14:28
package Doudya.Base;
/*********************************************************************/
/***  功能:图象验证码                                             ***/
/***  描述:生成一个4位的图片验证码,并将其保存在Session中         ***/
/***        其它位置可以用Session.getAttribute("validCode")来获取  ***/
/***  缺点:因为所有颜色和字体都是随机的,容易生成模糊图片         ***/
/***  优点:因为所有颜色和字体都是随机的,所以不容易破解           ***/
/***  作者:Doudya                                                 ***/
/***  QQ214395    欢迎共同研究                                     ***/
/*********************************************************************/


/**Servlet相关**/
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**输出对象**/
import java.io.OutputStream;
import java.io.IOException;
/**绘图对象**/
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.image.BufferedImage;
/**字体相关**/
import java.awt.GraphicsEnvironment;
import java.awt.Font;
/**图象输出**/
import javax.imageio.ImageIO;



public class validimg extends HttpServlet{
    static final long serialVersionUID = 19870121;
    public void init(){
        /*初始化Servlet*/
    }
    public void destory(){
        /*退出Servlet*/
    }
    public String tranPOST(String buffer_){/*编码翻译*/
        try{
            return java.net.URLDecoder.decode(buffer_, "UTF-8");
        }catch(Exception e){
        /*错误处理*/
            return null;
        }
    }
    public void doGet(HttpServletRequest request,HttpServletResponse response){
        try{
            doPost(request,response);
        }catch(Exception e){
        /*错误处理*/
        }
    }
    public void doPost(HttpServletRequest request,HttpServletResponse response){
        try{
            response.setContentType("image/jpeg");
            request.getSession().setAttribute("validCode",writeImg(response.getOutputStream()));
        }catch(Exception e){
        //错误处理
        }
    }
    public String writeImg(OutputStream out){
        int width = 75;
        int height = 18;
        /**应用绘图对象**/
        BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D gd = (Graphics2D)bi.getGraphics();
        /**绘制背景**/
        gd.setBackground(new Color(rnd(),rnd(),rnd()));
        gd.clearRect(0,0,width,height);
        /**设置字体**/
        Font font = new Font(getRndFontNames(),Font.PLAIN,24);
        gd.setFont(font);
        /**随机字串**/
        StringBuffer sb = new StringBuffer();
        int i;
        for(i=0;i<4 ;i++ ){
            sb.append(filter(rnd()));
        }
        /**设置颜色并输出**/
        /** 1 所有验证码颜色一致
        gd.setColor(new Color(rnd(),rnd(),rnd()));
        gd.drawString(sb.toString(), 0, 16); //这是普通方式,我想让所有字母颜色都不同
        **/
        /** 2 用随机颜色生成每个验证符**/
        String st = sb.toString();
        while(i>0){
            /**随机颜色,并进行色彩限定**/
            gd.setColor(new Color(rnd(),rnd(),rnd()));
            gd.drawString(st.substring(i-1,i),(i-1)*16+5,16);
            i--;
        }

/**清理现场**/
        gd.dispose();
        bi.flush();
/**绘制**/
        try{
            ImageIO.write(bi,"jpg",out);
        }catch(IOException e){
            System.out.println("Error in writeImg:" + e);
        }
        return st;
    }
/**随机生成0-255的数字**/
    public int rnd(){
        java.util.Random random = new java.util.Random();
        return random.nextInt(255);
    }
/**把除了大小写字母和数字外的字符全过滤掉**/
    public char filter(int k){
        if(k<65)k=48+(k%10);
        if(k>64&&k<96)k=65+(k%26);
        if(k>96)k=97+(k%26);
        return (char)k;
    }
/**取得一个随机字体**/
    public String getRndFontNames(){
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] k = ge.getAvailableFontFamilyNames();
        java.util.Random r = new java.util.Random();
        return k[r.nextInt(k.length)];
    }
}