JavaWeb中登錄模塊驗證碼(springMVC)


最近有需求在項目的登錄模塊加上驗證碼,在網上找了一些java寫的驗證碼,總算是找到了一個比較炫酷的,廢話不多說,上代碼:

1.首先是生成隨機數的Randoms類:

 1 2 
 3 import java.util.Random;
 4 
 5 public class Randoms {
 6     private static final Random RANDOM = new Random();
 7     //定義驗證碼字符.去除了O和I等容易混淆的字母
 8     public static final char ALPHA[]={'A','B','C','D','E','F','G','H','G','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'
 9             ,'a','b','c','d','e','f','g','h','i','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7','8','9'};
10  
11     /**
12      * 產生兩個數之間的隨機數
13      * @param min 小數
14      * @param max 比min大的數
15      * @return int 隨機數字
16      */
17     public static int num(int min, int max)
18     {
19         return min + RANDOM.nextInt(max - min);
20     }
21  
22     /**
23      * 產生0--num的隨機數,不包括num
24      * @param num 數字
25      * @return int 隨機數字
26      */
27     public static int num(int num)
28     {
29         return RANDOM.nextInt(num);
30     }
31  
32     public static char alpha()
33     {
34         return ALPHA[num(0, ALPHA.length)];
35     }
36 
37 }

2.然后是生成驗證碼接口Captcha(需要注意這里Randoms類是靜態導包,對應我上面第1步中的Randoms包路徑):

  1  2 
  3 import java.awt.*;
  4 import java.awt.image.BufferedImage;
  5 import java.io.OutputStream;
  6  
  7 
  8 import static com.gmsz.ylpt.common.utils.Randoms.num;
  9 import static com.gmsz.ylpt.common.utils.Randoms.alpha;
 10 /**
 11  * <p>驗證碼抽象類,暫時不支持中文</p>
 12  *
 13  * @author: cjz
 14  * 
 15  */
 16 public abstract class Captcha
 17 {
 18     protected Font font = new Font("Verdana", Font.ITALIC|Font.BOLD, 28);   // 字體
 19     protected int len = 5;  // 驗證碼隨機字符長度
 20     protected int width = 150;  // 驗證碼顯示跨度
 21     protected int height = 40;  // 驗證碼顯示高度
 22     private String chars = null;  // 隨機字符串
 23  
 24     /**
 25      * 生成隨機字符數組
 26      * @return 字符數組
 27      */
 28     protected char[] alphas()
 29     {
 30         char[] cs = new char[len];
 31         for(int i = 0;i<len;i++)
 32         {
 33             cs[i] = alpha();
 34         }
 35         chars = new String(cs);
 36         return cs;
 37     }
 38     public Font getFont()
 39     {
 40         return font;
 41     }
 42  
 43     public void setFont(Font font)
 44     {
 45         this.font = font;
 46     }
 47  
 48     public int getLen()
 49     {
 50         return len;
 51     }
 52  
 53     public void setLen(int len)
 54     {
 55         this.len = len;
 56     }
 57  
 58     public int getWidth()
 59     {
 60         return width;
 61     }
 62  
 63     public void setWidth(int width)
 64     {
 65         this.width = width;
 66     }
 67  
 68     public int getHeight()
 69     {
 70         return height;
 71     }
 72  
 73     public void setHeight(int height)
 74     {
 75         this.height = height;
 76     }
 77  
 78     /**
 79      * 給定范圍獲得隨機顏色
 80      * @return Color 隨機顏色
 81      */
 82     protected Color color(int fc, int bc)
 83     {
 84         if (fc > 255)
 85             fc = 255;
 86         if (bc > 255)
 87             bc = 255;
 88         int r = fc + num(bc - fc);
 89         int g = fc + num(bc - fc);
 90         int b = fc + num(bc - fc);
 91         return new Color(r, g, b);
 92     }
 93  
 94     /**
 95      * 驗證碼輸出,抽象方法,由子類實現
 96      * @param os 輸出流
 97      */
 98     public abstract BufferedImage out(OutputStream os);
 99  
100     /**
101      * 獲取隨機字符串
102      * @return string
103      */
104     public String text()
105     {
106         return chars;
107     }
108 }

3.繼承Captcha接口的SpecCaptcha類實現了父類的生成驗證碼的抽象方法:

 1 2 
 3 import static com.gmsz.ylpt.common.utils.Randoms.num;
 4 
 5 import java.awt.AlphaComposite;
 6 import java.awt.Color;
 7 import java.awt.Font;
 8 import java.awt.Graphics2D;
 9 import java.awt.image.BufferedImage;
10 import java.io.OutputStream;
11 
12 public class SpecCaptcha  extends Captcha{
13      public SpecCaptcha()
14         {
15         }
16         public SpecCaptcha(int width, int height)
17         {
18             this.width = width;
19             this.height = height;
20         }
21         public SpecCaptcha(int width, int height, int len){
22             this(width,height);
23             this.len = len;
24         }
25         public SpecCaptcha(int width, int height, int len, Font font){
26             this(width,height,len);
27             this.font = font;
28         }
29         /**
30          * 生成驗證碼
31          * @throws java.io.IOException IO異常
32          */
33         @Override
34         public BufferedImage out(OutputStream out){
35             return graphicsImage(alphas(), out);
36         }
37      
38         /**
39          * 畫隨機碼圖
40          * @param strs 文本
41          * @param out 輸出流
42          */
43         private BufferedImage graphicsImage(char[] strs, OutputStream out){
44                BufferedImage bi =null;
45                 bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
46                 Graphics2D g = (Graphics2D)bi.getGraphics();
47                 AlphaComposite ac3;
48                 Color color ;
49                 int len = strs.length;
50                 g.setColor(Color.WHITE);
51                 g.fillRect(0,0,width,height);
52                 // 隨機畫干擾的蛋蛋
53                 for(int i=0;i<15;i++){
54                     color = color(150, 250);
55                     g.setColor(color);
56                     g.drawOval(num(width), num(height), 5+num(10), 5+num(10));// 畫蛋蛋,有蛋的生活才精彩
57                     color = null;
58                 }
59                 g.setFont(font);
60                 int h  = height - ((height - font.getSize()) >>1),
61                     w = width/len,
62                     size = w-font.getSize()+1;
63                 /* 畫字符串 */
64                 for(int i=0;i<len;i++)
65                 {
66                     ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);// 指定透明度
67                     g.setComposite(ac3);
68                     color = new Color(20 + num(110), 20 + num(110), 20 + num(110));// 對每個字符都用隨機顏色
69                     g.setColor(color);
70                     g.drawString(strs[i]+"",(width-(len-i)*w)+size, h-4);
71                     color = null;
72                     ac3 = null;
73                 }
74             return bi;
75         }
76 
77 }

好了,到這里,這三個類就可以生成驗證碼了,那么如何將生成好的驗證碼加到項目中呢?我用的是SpringMVC框架,用戶打開登錄界面,會到controller中將生成好的驗證碼字符串放到session中(接口Captcha中有個text()方法返回一個驗證碼字符串),然后將生成好的驗證碼圖片放到servlert的輸出流中,jsp頁面去輸出流中把圖片取出來展示到前台即可。說干就干,首先上我的前台jsp代碼:

1 <div class="login-content-input login-content-input-code">
2     <div>
3                 驗證碼<input type="code"  name="password"           id="validateCode" value="" />
4     <img  id="validateCodeImg" src="<%=actionPath%>/getCode"    onclick="login.reloadValidateCode();" />
5     </div>
6     </div>                    

這里我只貼出了我項目中的驗證碼模塊的關鍵部分代碼,那些引入jquery.js,  jstl之類的我就忽略了。這里的<%=actionPath%>可以根據自己的項目路徑自行修改。下面是我的后台java代碼,也就是controller中的代碼:

/**
     * 生成驗證碼
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "getCode")
    public void validateCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //禁止圖像緩存
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        
        Captcha captcha = new SpecCaptcha(150,40,5);// png格式驗證碼
        ServletOutputStream out = response.getOutputStream();
        BufferedImage bi = captcha.out(out);
        //獲取驗證碼字符串放到session中,用於登錄時取出來驗證
        String verifyCode =   captcha.text();
        request.getSession().setAttribute("validateCode", verifyCode);
        //將圖像輸出到 servlet的輸出流中
        ImageIO.write(bi, "png", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    
    }

這里注釋也很詳細了,最終前台展示效果圖:,哈哈大功告成,當然還有一點就是 刷新驗證碼,刷新驗證碼其實就是重新去后台生成一個驗證碼,這里,我貼出我的js文件代碼:

/**
 * 點擊驗證碼刷新
 */
var login = login || {};

login.reloadValidateCode = function(){
    /**
     * 給url后面加一個隨機數,這樣,每次請求都會從后台取新生成的驗證碼
     * 不會再去緩存中取驗證碼
     */
    var randomNumber = new Date()+Math.floor(Math.random() * Math.pow(10, 8));
    $("#validateCodeImg").attr("src",commonutil.actionPath+"/getCode?random="+randomNumber);
}

這里需要稍微注意下的就是url后面的隨機數,保證不會從緩存中取驗證碼,說白了就是每次發送新的url請求去后台獲取驗證碼 。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM