jsp來實現 驗證碼 登錄案例 有圖 有碼

適用學習 對象 : java的 初學者 僅供參考-----------

開發 工具 idea ---- jdk8 ------ javaEE7 服務器tomcat 8.5

涉及javaWeb 基礎 : session request response

有圖 有碼

分析 需求

:使用jsp來實現的 驗證碼 的 實現 : login.jsp ------ LoginServlet -----
login.jsp -----------
form table 表單 : tr —td
======& jsp的預覽 要在 服務器 裏 運行 :
--------- action 的請求的 是 :
servlet :---------- LoginSrevlet ---------

設置請求request的  編碼  :  
所有的  request 的參數:
獲取驗證碼  ??
將 用戶用戶的 信息 
5 判斷 用戶
信息的  封裝到user 對象 裏    
session   
   判斷  用戶  的 獲取 程序 生成驗證碼 :   與 用戶輸入 是否 保持一致  

先判斷  驗證碼   在 判斷 用戶 :減少 的  數據庫 的訪問次數的 壓力
 if 一致  : 
          if  用戶名與密碼 
         正確就  的登錄成功 

   else  
      1: 給提示 
      2:  重定向到登錄頁面    =========  重定向
 這裏 轉發到Session  裏 也是可以 的

-----  門都 沒有進 就得重來 了-------

else   不一致    : 

  1:      提示驗證 錯誤的 信息  
  2:   轉發  跳轉到   登錄頁面 裏 ========= 轉發 

錯誤信息 只在jsp 裏共享-----v 一次request 裏 無需其他人知道
只是 起碼都登錄 了 驗證碼的錯誤

  • 涉及

一個轉發與 重定向 是的 區別 :

   關於request 與的 使用與否
 request 域裏就會  用轉發    其他的就是 重定向          

使用 中 路徑與否:

轉發---相對路徑           重定向---絕對路徑

---- 關於域對象的 使用場景 :

 用戶名  與登錄 會  經常的使用 存在  Session  裏  ------


具體實施  : 將原來 一邊寫好 驗證碼的  servlet、   粘貼過來    : 

  據需要在  的改進   : 使用個的是StringBuild   ===== 

  生成 驗證碼 在Session域 裏     域 ------ 操作方法  Attribute
 防止空指針異常 ---=========
 驗證碼忽略大小寫  -------
  • 注意 :

      form  表單  提交到servlet   裏 
    

    先判斷 :驗證碼錯誤就少判斷一次數據庫

    也許: 可能看不出來的
     ------  null 值得判斷 :sjp 裏直接的就進行的 三元判斷式
    
     *******  用一次就是失效 : 前面一點獲取就 後面就會
       removeAttribute()  是的 使用
    

    ============ 編碼的實施 ===============

    • 創建前端頁面 :

      ---  from 表單的額 action  到指定的 servlet 裏   method= post    
      ---table  表格  裏
        tr  -- td  裏input   Type與name  的屬性的 定義
       ---  分別定義的的是   ;  -----
       ----用戶名 type text  
       ----密碼  type password
        ----  驗證碼  type text
        ----img ----td  的 colspan=2 跨2行
       ----  圖片 :  img   的id =“img”   src =“指定的servlet”
           
      ---- submit -----value:“登錄” td  的 colspan=2 跨2行 
      

使用js 來進行 切換 驗證碼 :

    Windows  調用 onload  的回調函數 ‘function(){} 裏’
通過id  獲取標籤體  :getElementById(“img”)onlick=function(){
this  調用當前的獲取的標籤體的img    
調用src 指定的 方法 裏  拼接time 值參數 的時間戳  ?time”+: 
new Date().getTime()

----- 後端的繼續編寫 ---------------

  創建servlet  頁面  : 
  獲取所有請求的參數  :request.getPrimaterMap()
 獲取Map  --- 操作數據庫 來做  ======

 這不用數據庫的操作  ----  需要你   完善 數據庫的
 分別 獲取參數  的: 
     request.getParameter(“  username ”)  。。password  。。checkCode。。
   

 ----  因爲 是2次請求 :  from表單裏面  的   增加  驗證碼 的這次請求
 將生成的碼值   儲存 到  Session 裏    -------  然後 在 loginServlet 裏   對比判斷  即可  

CheckCodeServlet 裏 ==========

  用StringBuild  的 append( )方法 來咋for  裏 進行拼接 ---
            ---  用  toString ()  轉爲字符串   :  
 //  存入session 裏  :   ----
 request.getSession().setAttribute("","");  鍵 定義名稱  ,
  值  就是---- StringBuild  的值

在這裏插入圖片描述

loginServlet 裏 :========== 繼續

獲取Session的 域裏 儲存的  剛纔的 生成  的 驗證碼 ;
--- request.getSession().getAttribuet("參數名稱")  ;
----- 返回一個 object對象  強轉爲  String: 
忽略大小寫的 的equalsIgnoreCaes(checkCode)

–### 重定向 範圍 域 基於Session 域 :

    setAttribute(“”username)
 --###  重定向 到 成功的頁面 : 參數裏  ----獲取 虛擬路徑 的方法  request.getContextPath()+
-----else :
 轉發的域  基於request 域裏  -----  setAttribute()設置鍵值對的信息  : 轉發到登錄 頁面  : 

轉發:

 request.getRequestDispatcher("").forward();   
 ---- 轉發的不寫 虛擬路徑  :    

----- – 寫到這裏 就要準備 success.jspde信息 : 是 :

    <h1><%=request.getSession().getAttribute("user")%>歡迎你</h1>   這裏的  user  就是 要儲存的  信息

------ 然後 在login.jsp 裏 :----------------------------

-----編寫的的2個div 
    獲取2次判斷  爲錯誤 的 Attribute 裏的  信息 
效果 :  對於的用戶名與  密碼名 的    驗證碼  輸入的錯誤的提示  :  

test 測試 : ===============================

在這裏插入圖片描述
 
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

要優化的 的是

------ 在login。jsp 裏做到的

1:----  null  的顯示的  優化 :   使用 三元表達式   在login  的  這 裏     
  三元表達式的   格式  :     ?:     
  ----- 2元 以 ? 問號的左右爲 前後條件 條件邏輯
 ----- 的前置成立 就執行 ?問號後面的: 冒號 爲else 的條件 
2: 驗證碼的優化  -------- 

bug描述 : 瀏覽器裏 當前已經登錄 後 當我們 建點擊瀏覽器裏 後退的 的時候 依然還是可以登錄的

3: 然後要設置的 是: 空指針異常的 判斷  字符串!=null

=============

完整代碼 呈現

前端的代碼的 呈現 —============

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script>
       window.onload=function () {
           document.getElementById("img").onclick=function () {
               this.src="/fhw/image01?time="+new Date().getTime();
           }
       }
    </script>
    <style>
        div{
            color:firebrick;
        }
    </style>
</head>
<body>

 <form action="/fhw/loginServlet" method="post">
     <table>
         <tr>
             <td>用戶名</td>
             <td><input type="text" name="username"></td>
         </tr>
         <tr>
             <td>密碼</td>
             <td><input type="password" name="password"></td>
         </tr>

         <tr>
             <td>驗證碼</td>
             <td><input type="text" name="checkCode"></td>
         </tr>

      <tr>
         <td colspan="2"><img  id="img" src="/fhw/image01"></td>
       </tr>

      <tr>
         <td colspan="2"><input type="submit" value="登錄"></td>
      </tr>



     </table>
 </form>

<%-- 直接用CSS 獲取標籤 給紅色是的指示 --%>

<%=request.getAttribute("cc_error")==null?"":request.getAttribute("cc_error")%>
<%-- 的驗證碼錯誤的信息 --%>
<%=request.getAttribute("login_error")==null?"":request.getAttribute("login_error")%>
<%-- 登錄錯誤的信息--%>

驗證碼的servlet ===================


package com.fhw.web.yanzhengma;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //response.setContentType("text/html;charset=utf-8");
        /*  已知在前端裏  請求到 的 參數在request 域 裏  在數據庫   裏直接的  所有的請求  當前不用數據庫的  就直接 進行的  */
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");
        //  去 CheckCode  使用 改進獲取  生成的 驗證碼 數據存儲 到Session裏  ===
        // 然後在 當前 Session 裏獲取 到 驗證碼   進行判斷
        HttpSession session = request.getSession();
        String  checkCoder_session = (String) session.getAttribute("check_code");
       session.removeAttribute("check_code");// 每次都是一個 新的
        // session  與的裏獲取生成的  驗證碼 equals 客戶端裏請求request 域 比較
        if (checkCoder_session!=null && checkCoder_session.equalsIgnoreCase(checkCode)){
            //  空指針異常的 判斷 && 忽略 大小寫,的比較
            // 驗證碼正確
            //  判斷用戶的 和密碼 是否一致 :   else :重定向  到
            if ("fhw".equals(username)&&"123".equals(password)){//需要UserDao 到數據庫 裏
                //  登錄成功 : 重定向 :
        session.setAttribute("user",username);
        response.sendRedirect(request.getContextPath()+"/successLogin.jsp");
            }else{//登錄失敗
                request.setAttribute("login_error","用戶或密碼名錯誤");
                //轉發到頁面
                request.getRequestDispatcher("/login.jsp").forward(request,response);
            }
        }else{// --------登錄頁面
            request.setAttribute("cc_error","驗證碼錯誤");
            //轉發到頁面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        this.doPost(request, response);
    }
}

登錄的loginservlet ===========

package com.fhw.web.yanzhengma;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //response.setContentType("text/html;charset=utf-8");
        /*  已知在前端裏  請求到 的 參數在request 域 裏  在數據庫   裏直接的  所有的請求  當前不用數據庫的  就直接 進行的  */
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");
        //  去 CheckCode  使用 改進獲取  生成的 驗證碼 數據存儲 到Session裏  ===
        // 然後在 當前 Session 裏獲取 到 驗證碼   進行判斷
        HttpSession session = request.getSession();
        String  checkCoder_session = (String) session.getAttribute("check_code");
       session.removeAttribute("check_code");// 每次都是一個 新的
        // session  與的裏獲取生成的  驗證碼 equals 客戶端裏請求request 域 比較
        if (checkCoder_session!=null && checkCoder_session.equalsIgnoreCase(checkCode)){
            //  空指針異常的 判斷 && 忽略 大小寫,的比較
            // 驗證碼正確
            //  判斷用戶的 和密碼 是否一致 :   else :重定向  到
            if ("fhw".equals(username)&&"123".equals(password)){//需要UserDao 到數據庫 裏
                //  登錄成功 : 重定向 :
        session.setAttribute("user",username);
        response.sendRedirect(request.getContextPath()+"/successLogin.jsp");
            }else{//登錄失敗
                request.setAttribute("login_error","用戶或密碼名錯誤");
                //轉發到頁面
                request.getRequestDispatcher("/login.jsp").forward(request,response);
            }
        }else{// --------登錄頁面
            request.setAttribute("cc_error","驗證碼錯誤");
            //轉發到頁面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        this.doPost(request, response);
    }
}

success 成功 前端頁面 :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1><%=request.getSession().getAttribute("user")%>歡迎你</h1>
</body>
</html>

============== 總結的提問 : ??? 用Session ==============
生成驗證碼 放到Session 域 裏 的 原因 :

  每次請求是可以 共享 
 request  域 i是 : 客戶端每次輸入的 請求:--- 在request  裏  用 parameter () 
 ?用Attribute 也可以嗎 ?????? 
請求request  參數裏的額 驗證碼: 客戶端       === 再 對比 ===  
Session  域  服務器 裏的servlet 類生成  的驗證碼:
=========   形成驗證的  

=============Attribute 與 parameter 的區別 =========

 ------ Attribute(服務端 屬性 : 4個域 中 的信息)
------ parameter(客戶端 參數:get方法:URL   post 請求是request請求體) 

來源:

 parameter參數()-----客戶端(瀏覽器)由用戶提供的,若是GET方法是從
                URL中 提供的,若是POST方法是從請求體(request body)中提供的; 
    
Attribute-屬性----服務器端  組件(JSP或者Servlet)利用requst.setAttribute()  設置的

操作:

parameter參數--------值---只能讀取不能修改,get讀取用request.getParameter(); 
Attribute屬性------值---既可以讀取亦可以修改,讀取可以使用request.setAttribute(),設置可使用request.getAttribute()

數據:

 parameter參數--------String類型看待,並且客戶端的參數值只能是簡單類型的值,不能是複雜類型,比如對象。 
 Attribute 屬性--------值可以是任意一個Object類型。 

共同點

二者的值都被封裝在request對象中。 

============

request 是在 客戶端嗎

:============

     不是 : request  是 服務器 創建 實現  HttpServlet 的HttpservletRequest類 --  肯定在 服務端 裏
 用來  在servlet  頁面  ==編寫程序  獲取客戶端 請求  的參數  :        
 ----- 而 response 同樣也是這樣的 

客戶端 裏Cookie 的都是怎樣的 :==========

有Cookie  信息   java web  裏 在servlet  頁面裏 創建的 Cookie    
 操作Cookie   getName  setValie  Cookie  鍵,值    setMaxAge()裏通過毫秒值的   正數 : 負數 一次性(Cookie的默認, 零0 就是刪除

Cookie只能 侷限: 存儲 字符串, 大小有限 ,信息不安全,

cookie  就是 客戶端的 請求 ;-------人機交流的基本就是 字符串 來進行的

寫到cookie 在 到Session 的 :

   Session 就是 基於Cookie 來的id   來創建   在服務端  的  
細緻的: 初次請求有了Cookie信息 : 請求 到了 服務端裏 服務器會根據   請求裏的
    cookie  id  創建Session  建立本次會話

第一次請求 與 響應就 建立了 本次回話 的初始化

【基於】cookie與Session組成立  web的 會話 :
本次 會話 灰有許多 的請求 與響應(交流)    : 每次  有求必應

==

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章