Java Servlet實現簡單的驗證碼生成

  驗證碼存在的意義:很多網站爲了防止用戶利用機器人自動註冊、登陸、灌水,都採用了驗證碼技術。所謂驗證碼,就是將一串隨機產生的數字或符號,生成一幅圖片,圖片里加上一些干擾象素(防止OCR),由用戶肉眼識別其中的驗證碼信息,輸入表單提交網站驗證,驗證成功後才能使用某項功能。php

  

  就是相似這個樣子滴,PS:(前端頁面真不想寫,太麻煩了0.0)。html


  思考:1.驗證碼的圖片資源哪裏來?                         前端

     2.如何實現點擊圖片更換驗證碼? java

     3.如何檢驗用戶輸入驗證碼與生成驗證碼?web

     4.如何返回並得到檢驗結果?ajax

     5.晚飯吃什麼...........午餐吃什麼...........瀏覽器


 解決:1.在生成圖片的Servlet中設置數據類型爲圖片--->resp.setContentType("image/jpeg");並將生成的圖片輸入到 response中,在這過程當中生成的驗證碼字符串須要存放到session中,爲後面的驗證取數據時做依據。緩存

    2.在js代碼中添加函數,改變img的src資源---->codeImg.src="CodeImg?d="+Math.random()這裏須要注意一點:若是不追加一個隨機數,瀏覽器的緩存影響,那麼每次點擊都是同一Servlet產生的圖片,起不到改變驗證碼的效果,這裏有幾種方法供參考:服務器

     一. GET請求URL後加隨機數,讓服務器認爲不是相同的請求。也能夠傳一個隨機的參數。 例 http://www.example.com/index.php?class=aitcle&page=5&_t=」 + new Date().getTime() 
     二. 在ajax發送請求前加上 xmlHttpRequest.setRequestHeader(「If-Modified-Since」,」0」) 
     三. 在ajax發送請求前加上 xmlHttpRequest.setRequestHeader(「Cache-Control」,」no-cache」); 
     四. 使用POST代替GET,瀏覽器不會對POST作緩存
session

   3.在檢驗驗證碼的Servlet中,獲取解決1中session存放的驗證碼、獲取用戶表單提交的驗證碼,進行比較,往session中存放比較結果,返回JSP驗證頁面。

  4.JSP驗證頁面經過el表達式獲取存放在session中的比較結果,並顯示在span標籤中。

  5.人生一大困惑.....


 

 下面上簡易版代碼(若有紕漏,望指教,多謝):

  結構:JSP驗證碼界面、Servlet圖片生成、Servlet邏輯判斷驗證碼

 

VerifyCode.jsp--驗證界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>驗證碼測試</title>
    <%--外聯CSS樣式--%>
    <style>
        form{
            border: 1px solid darkcyan;
            width: 300px;
            height: 300px;
            margin: 0px auto;
            text-align: center;
        }

        img{
            margin: 30px;
        }
    </style>

    <%--js改變驗證碼函數定義--%>
    <script>
        function changeCode() {
            var codeImg=document.getElementById("verifyCode");
            //這裏URL後追加隨機數,使程序每次訪問的都是不一樣的資源,防止瀏覽器緩存,即產生不一樣的驗證碼
            codeImg.src="VerifyCodeImg?d="+Math.random();
        }
    </script>
</head>
<body>
    <h3>一個驗證碼的測試</h3>
    <%--經過表單提交到servlet中驗證,並返回驗證結果在span標籤中用el表達式獲取messageShow中攜帶的信息--%>
    <form action="CheckVerifyCode" method="get">
        <h3>驗證碼</h3>

        <%--src爲圖片生成的Servlet,onclick實現函數變換img的src--%>
        <img src="VerifyCodeImg" alt="Loading" onclick="changeCode()" id="verifyCode">

        <%--用戶輸入--%>
        <input type="text" name="userCode" id="userCode"><br><br>
        <input type="submit" value="提交驗證"><br><br>
        
        <%--el獲取存在session中的比較結果--%>
        <span id="messageShow">${sessionScope.messageShow}</span>
    </form>
</body>
</html>

 

 

VerifyCodeImg--圖片生成
public class VerifyCodeImg extends HttpServlet{
    private static final int WIDTH = 100;//設置驗證碼圖片寬度
    private static final int HEIGHT = 30;//設置驗證碼圖片高度
    private static final int LENGTH = 4;//設置驗證碼長度
    public static final int LINECOUNT=20;//干擾線的數目

    //驗證碼的字符庫
    private static final String str="0123456789"+
                                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
                                    "abcdefghijklmnopqrstuvwxyz";

    //經過隨機數取字符庫中的字符組合成4位驗證碼
    private static Random random=new Random();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //設置數據類型爲圖片
        resp.setContentType("image/jpeg");

        //設置不進行緩存
        resp.setHeader("pragma", "no-cache");
        resp.setHeader("cache-control", "no-cache");
        resp.setHeader("expires", "0");



        //獲取畫筆
        BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_3BYTE_BGR);
        Graphics g=image.getGraphics();

        //設置背景顏色並繪製矩形背景
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        //驗證碼的繪製
        String code=drawChar(g);
        System.out.println("驗證碼:"+code);


        //隨機線的繪製
        for (int i=0;i<LINECOUNT;i++){
            drawLine(g);
        }

        //在session中存入當前的code碼,便於驗證
        req.getSession().setAttribute("code",code);

        //繪製圖片
        g.dispose();

        //將圖片輸出到response中
        ImageIO.write(image, "JPEG", resp.getOutputStream());
    }


    //獲取不一樣顏色
    public  Color getColor(){
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }

    //獲取字體樣式
    public Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 20);
    }

    //繪製字符
    public String drawChar(Graphics g){
        String code="";
        g.setFont(getFont());
        for (int i=0;i<LENGTH;i++){
            char c=str.charAt(random.nextInt(str.length()));
            g.setColor(getColor());
            g.drawString(c+"", 20* i + 10, 20);
            code=code+c;
        }
        return code;
    }

    //繪製隨機線
    public  void drawLine(Graphics g) {
        int x = random.nextInt(WIDTH);
        int y = random.nextInt(HEIGHT);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.setColor(getColor());
        g.drawLine(x, y, x + xl, y + yl);
    }
}

 

 
CheckVerifyCode--邏輯判斷
public class CheckVerifyCode extends HttpServlet {
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //返回的信息提示
        String messageShow="";

        //用戶輸入的驗證碼
        String userCode = request.getParameter("userCode");

        //VerifyCodeImg存在session中的驗證碼
        String rightCode=null;
        Object code = request.getSession().getAttribute("code");
        if(code!=null){
            rightCode=(String) code;
        }

        //用戶輸入和生成驗證碼的比較,並生成不一樣的信息提示
        if(userCode.equalsIgnoreCase(rightCode)){
            messageShow="驗證成功!!!";
        }else{
            messageShow="驗證失敗???";
        }

        //在session中存放信息提示
        request.getSession().setAttribute("messageShow",messageShow);

        //重定向回JSP驗證界面,並提示
        response.sendRedirect("VerifyCode.jsp");
    }
}

 

 注意:Servlet記得要配置web.xml文件,不然找不見
相關文章
相關標籤/搜索