教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

JAVA培訓(xùn)之登錄案例之添加驗(yàn)證碼案例詳解

更新時(shí)間:2016年09月21日11時(shí)58分 來源:傳智播客JAVA培訓(xùn)學(xué)院 瀏覽次數(shù):

經(jīng)過登錄案例之添加驗(yàn)證碼案例的分析,大家對(duì)本案例的功能有了一定的了解,下面我們就來實(shí)現(xiàn)該案例,點(diǎn)擊此處 可以下載本案例源代碼,具體如下:
(1)本案例是在HttpSession第二例中的案例的基礎(chǔ)上完成的,案例的其他功能詳情可以參考HttpSession第二例;下面我們對(duì)Example22中的login.jsp頁面稍作修改,如例1-1所示:
例1-1 login.jsp
<body>
<%-- 本頁面提供登錄表單,還要顯示錯(cuò)誤信息 --%>
<h1>登錄</h1>
<%
/*
讀取名為uname的Cookie!
如果為空顯示:""
如果不為空顯示:Cookie的值
*/
String uname = "";
Cookie[] cs = request.getCookies();//獲取請(qǐng)求中所有的cookie
if(cs != null) {// 如果存在cookie
    for(Cookie c : cs) {//循環(huán)遍歷所有的cookie
       if("uname".equals(c.getName())) {//查找名為uname的cookie
           uname = c.getValue();//獲取這個(gè)cookie的值,給uname這個(gè)變量
       }
    }
}
%>
<%
String message = "";
String msg = (String)request.getAttribute("msg");//獲取request域中的名為msg的屬性
if(msg != null) {
       message = msg;
}
%>
<font color="red"><b><%=message %> </b></font>
<form action="/Example22/LoginServlet" method="post">
           <%-- 把cookie中的用戶名顯示到用戶名文本框中 --%>
    用戶名:<input type="text" name="username" value="<%=uname%>"/><br/>
    密 碼:<input type="password" name="password"/><br/>
    驗(yàn)證碼:<input type="text" name="verifyCode" size="3"/>
           <img id="img" src="/Example22/VerifyCodeServlet"/><br>
    <input type="submit" value="登錄"/>
</form>
  </body>
在例1-1中,新添加了一個(gè)表單項(xiàng):驗(yàn)證碼,并且還有一個(gè)<img>標(biāo)簽,該標(biāo)簽的src屬性值為“/Example22/VerifyCodeServlet”,后面我們會(huì)新建一個(gè)名為VerifyCodeSerlvet的Servlet類。
(2)在該應(yīng)用下,新建一個(gè)package,名為cn.itcast.utils,然后將生成驗(yàn)證碼圖片中的VerifyCode類放在該package下。
(3)在該應(yīng)用下,新建一個(gè)Servlet類,名稱為VerifyCodeServlet,其在web.xml文件中配置的訪問路徑為“/VerifyCodeServlet”,主要代碼如例1-2所示:
例1-2 VerifyCodeServlet.java
public class VerifyCodeServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       /*
        * 1. 生成圖片
        * 2. 保存圖片上的文本到session域中
        * 3. 把圖片響應(yīng)給客戶端
        */
       VerifyCode vc = new VerifyCode();
       BufferedImage image = vc.getImage();
       request.getSession().setAttribute("session_vcode", vc.getText());//保存圖片上的文本到session域
       VerifyCode.output(image, response.getOutputStream());
    }
}
在例1-2中,首先通過VerifyCode幫助類獲取一張圖片,然后將圖片上的驗(yàn)證碼保存在session域中,最后調(diào)用VerifyCode類的output()方法,將圖片保存在輸出流中,由于我們要將圖片輸出在瀏覽器端,所以這里的輸出流是response.getOutputStream()字節(jié)輸出流,通過這個(gè)流就可以將圖片顯示在瀏覽器端。
(4)將Example22發(fā)布到服務(wù)器中,然后開啟服務(wù)器,然后在瀏覽器端訪問:http://localhost:8080/Example22/login.jsp,并使用HttpWatch工具查看請(qǐng)求信息,如圖1-1所示:

圖1-1 訪問login.jsp
由圖1-1可知,我們?cè)谠L問login.jsp時(shí),瀏覽器一共發(fā)送了兩個(gè)請(qǐng)求:一個(gè)是請(qǐng)求login.jsp,另一個(gè)是請(qǐng)求VerifyCodeServlet。
(5)瀏覽器的顯示結(jié)果如圖1-2所示:

圖1-2 瀏覽器顯示結(jié)果
圖1-2中,生成的驗(yàn)證碼圖片中的值為“28hS”。
(6)下面對(duì)應(yīng)用中的LoginServlet進(jìn)行修改,這里只給出添加的代碼,如例1-3所示:
例1-3 LoginServlet.java
    /*
        * 校驗(yàn)驗(yàn)證碼
        * 1. 從session中獲取正確的驗(yàn)證碼
        * 2. 從表單中獲取用戶填寫的驗(yàn)證碼
        * 3. 進(jìn)行比較!
        * 4. 如果相同,向下運(yùn)行,否則保存錯(cuò)誤信息到request域,轉(zhuǎn)發(fā)到login.jsp
        */
String sessionCode=(String)request.getSession().
getAttribute("session_vcode");
       String paramCode = request.getParameter("verifyCode");
       if(!paramCode.equalsIgnoreCase(sessionCode)) {
           request.setAttribute("msg", "驗(yàn)證碼錯(cuò)誤!");
           request.getRequestDispatcher("/session/login.jsp").
forward(request, response);
           return;
}
例1-3中,if語句中轉(zhuǎn)發(fā)代碼之后要使用“return”關(guān)鍵字結(jié)束方法的執(zhí)行,如果不使用return關(guān)鍵字,那么該方法還會(huì)繼續(xù)執(zhí)行下去,如果后面有重定向或轉(zhuǎn)發(fā)語句那么就會(huì)拋異常。
(7)重新啟動(dòng)服務(wù)器,在瀏覽器端再次訪問login.jsp,然后輸入用戶名:zhagnsan,密碼:123,如圖1-3所示:

圖1-3 瀏覽器顯示結(jié)果
圖1-3中,正確的驗(yàn)證碼是“QYCe”,而輸入的驗(yàn)證碼是“qyce”,由于在LoginServlet中驗(yàn)證碼忽略大小寫,所以這樣寫也是正確的。
(8)點(diǎn)擊圖1-3中的“登錄”按鈕,瀏覽器顯示結(jié)果如圖1-4所示:

圖1-4 瀏覽器顯示結(jié)果
(9)再次訪問login.jsp,用戶名和密碼輸入的仍然是zhangsan,123,如圖1-5所示:

圖1-5 瀏覽器顯示結(jié)果
(10)點(diǎn)擊圖1-5中的“登錄”按鈕,瀏覽器顯示結(jié)果如圖1-6所示:

圖1-6 瀏覽器顯示結(jié)果
驗(yàn)證碼不正確,那么就轉(zhuǎn)發(fā)到login.jsp,并在瀏覽器端打印“驗(yàn)證碼錯(cuò)誤”。
(11)在瀏覽器端訪問login.jsp頁面,再次訪問該頁面時(shí),使用HttpWatch工具獲取請(qǐng)求信息,如圖1-7所示:

圖1-7 請(qǐng)求信息
圖1-7中,訪問login.jsp頁面,服務(wù)器響應(yīng)200狀態(tài)碼,但是訪問VerifyCodeServlet走的是瀏覽器的緩存,也就是說頁面中的驗(yàn)證碼不改變。
(12)為了解決以上問題,我們對(duì)login.jsp頁面做些修改,在驗(yàn)證碼后面添加一個(gè)超鏈接“換一張”,并添加一段javascript代碼,如例1-4所示:
<script type="text/javascript">
function _change() {
    /*
    1. 得到img元素
    2. 修改其src為/day11_3/VerifyCodeServlet
    */
    var imgEle = document.getElementById("img");
    imgEle.src = "/Example22/VerifyCodeServlet?a=" + new Date().getTime();
}
</script>
... ...
<a href="javascript:_change()">換一張</a>
例1-4中,當(dāng)點(diǎn)擊超鏈接“換一張”時(shí)就執(zhí)行_change()函數(shù),該函數(shù)首先獲得id為“img”的標(biāo)簽,如果設(shè)置該標(biāo)簽的src屬性的值為“/Example22/VerifyCodeServlet”,那么還是會(huì)出現(xiàn)圖1-7所示結(jié)果,所以我們?cè)谠撀窂胶竺嫣砑恿艘粋€(gè)請(qǐng)求參數(shù)a,該參數(shù)的值是當(dāng)前時(shí)間的毫秒值,那么a的值就會(huì)隨著時(shí)間的改變而改變,因此每次點(diǎn)擊超鏈接,服務(wù)器就認(rèn)為是一次新的請(qǐng)求,從而做出響應(yīng)。
(13)在瀏覽器段再次訪問login.jsp,如圖1-8所示:

圖1-8 瀏覽器顯示結(jié)果
(14)點(diǎn)擊圖1-8中的“換一張”,瀏覽器顯示結(jié)果如圖1-9所示:

圖1-9瀏覽器顯示結(jié)果
圖1-8與圖1-9中的驗(yàn)證碼不相同,表明代碼有效。

本文版權(quán)歸傳智播客Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客Java培訓(xùn)學(xué)院
首發(fā):http://xamj520.com/javaee
0 分享到:
和我們?cè)诰€交談!