• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • JAVAWEB開發之JSP、EL、及會話技術(Cookie和Session)的使用詳解

    Servlet的缺點

    開發人員要十分熟悉JAVA
    不利于頁面調試和維護(修改,重新編譯)
    很難利用網頁設計工具進行頁面設計(HTML內容導入到servlet中,用PrintWriter的對象進行輸出)

    JSP簡介

    JSP(Java Server Pages) 與Java Servlet一樣,是在服務器端執行的,不同的是JSP先由服務器編譯部署成Servlet執行。
    JSP技術的企業最佳實踐(生成HTML內容)
    新的JSP2.0規范版本包括新的功能(EL表達式,新增的Simple Tag和Tag File,web.xml新增<jsp:config>元素)

    1.What is JSP
    JSP( JavaServer Pages )是由Sun 公司倡導、許多別的公司參與一起建立的一種新動態網頁
    技術標準,類似其他技術標準,如ASP、PHP 或是ColdFusion,等等。
    在傳統的網頁HTML 文件( *.htm,*.html )中加入Java程序片段( Scriptlet )和JSP標簽,構成了JSP 網頁(*.jsp)。Servlet/JSP Container 收到客戶端發出的請求時,首先執行其中的程序片段,然后將執行結果以HTML格式響應給客戶端。其中程序片段可以是:操作數據庫、重新定向網頁以及發送 E-Mail 等等,這些都是建立動態網站所需要的功能。所有程序操作都在服務器端執行,網絡上傳送給客戶端的僅是得到的結果,與客戶端的瀏覽器無關,因此,JSP 稱為Server-SideLanguage。

    2.Microsoft 和 Sun 都提供它們各自品牌的服務器頁面。Sun提供JavaServer Pages (JSP)而 Microsoft 提供 Active Server Pages(ASP)。JSP 和 ASP 都設計成使開發者能夠從后端系統產生動態頁面。
    雖然表面看起來相似,ASP 和JSP仍有一些不同之處:
    • JSP 是平臺獨立性的,一次編寫,隨處運行;
    • 開發者通過Java Community Process(JCP)指引方向;
    • JSP 開發者可以通過定制標簽擴展JSP標簽庫;
    • JavaBeans 和 Enterprise JavaBeans (EJB) 可以和JSP一起使用,增強可重用性和減小維護。
    • JSP 可以存取其他一些Java 庫,包括Java 數據庫連接(JDBC),Java Mail,Java Message
    • Service(JMS),以及JNDI。
    • JSP 編譯成二進制類文件,不需要在每次請求時進行解釋;
    • JSP 有廣泛的支持,包括工具,容器和服務器。

    JSP的運行原理


    JSP的執行過程:
    (1)客戶端發出Request請求
    (2)JSP Container將JSP翻譯成Servlet源代碼
    (3)將產生的Servlet源代碼經過編譯后,加載到內存執行。
    (4)把結果Response(響應)發送至客戶端
    JSP和Servlet的執行效率相差不大,只是第一次執行JSP頁面時需要進行編譯。
    一般都會以為JSP 的執行性能會和Servlet 相差很多,其實執行性能上的差別只在第一次的執行。因為JSP 在執行第一次后,會被編譯成Servlet 的類文件,即為XXX.class,當再重復調用執行時,就直接執行第一次所產生的Servlet,而不用再重新把JSP編譯成Servlet。因此,除了第一次的編譯會花較久的時間之外,之后JSP 和Servlet 的執行速度就幾乎相同了。
    在執行JSP 網頁時,通常可分為兩個時期:轉譯時期(Translation Time)和請求時期(Request Time) 。
    1). JSP文件先要被服務器翻譯成Java文件(Servlet),在tomcat中翻譯后的Java文件在tomcat下的 work/Catalina /localhost 中相應名字的應用目錄里。
    2). 編譯成Java(Servlet)文件
    3). 運行.class文件
    Tomcat的全局配置文件$CATALINA_HOME/conf/web.xml
    在Tomcat下的conf目錄中的web.xml是服務器全局的配置文件,其中要想關閉列表顯示把
    <init-param>
    <param-name>listings</param-name>
    <param-value>false</param-value>
    </init-param>
    修改為false

    JSP 程序的翻譯過程



    JSP生命周期
    public void _jspInit() {…}
    public void _jspDestroy() {…}
    public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException {…}
    上面的代碼會翻譯到 _jspService 方法中

    JSP腳本元素

    Declaration(聲明)

    • 聲明的格式: <%! 聲明1;[聲明2];……%>
    • 聲明的作用范圍是整個JSP頁面,同時它只在一個JSP頁面有效
    • 聲明的類型包括:變量,方法,類
    每一個聲明僅在一個頁面中有效,如果每個頁面都用到一些聲明,最好把它們寫成一個單
    獨的JSP 網頁,然后用<%@ include %>或<jsp:include >元素包含進來。

    使用<%! %>方式所聲明的變量為成員變量,即表示:若同時n 個用戶在執行此JSP網頁時,
    將會共享此變量。強烈建議不要使用<%! %>來聲明變量。

    若要聲明變量時,請直接在<% %>之中聲明使用即可。
    統計用戶訪問量程序代碼
    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <%!
    int count = 0 ;
    %>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>你是第<%=++count%>個訪問本網站的用戶!</h1>
    </body>
    </html>
    

    Expression(表達式)

    語法格式
    • <%= 變量或表達式 %>
    • 表達式的計算結果轉換成字符串
    • 使用隱含對象out進行輸出
    • 范例<%=“abc” %> 等價于 out.print(“abc”);
    • JSP腳本表達式中的變量或表達式后面不能有分號(;)

    Scriptlets(代碼塊)

    • 語法格式:<% java code %>
    • 在“<%”和”%>”之間插入java程序片,一個JSP頁面可以有許多程序片,這些代碼塊將被JSP服務器按照順序執行
    • 在一個代碼塊中聲明的變量是JSP頁面的局部變量,只在當前頁面有效

    EL快速入門:

    • EL 全名為Expression Language
    • 語法:${標識符}
    • 常用功能
    • 獲取各種域中存儲的數據
    <%=request.getAttribute(“name”);>
    ${requestScope.name}

    會話

    (1)什么是會話?
    會話可以簡單的理解為:用戶打開一個瀏覽器,點擊多個超鏈接,訪問服務器多個web資源然后關閉瀏覽器,整個過程稱之為一個會話。
    (2)會話過程中要解決的一些問題?
    每個用戶與服務器進行交互的過程中,各自會有一些數據,程序要想辦法保存每個用戶的數據。
    例如:用戶點擊超鏈接通過一個Servlet購買了一個商品,程序應該保存用戶購買的商品,以便于用戶結賬Servlet時,結賬Servlet可以得到用戶商品為用戶結賬。
    問題:request和ServletContext域是否可以保存用戶的購物信息呢?
    答案是不可以:

    原因如下:
    request域的范圍是一次請求,即使利用追加和轉發的方式保存了購物信息,當關閉鏈接或關閉瀏覽器或者以別的方式(例如重定向 或直接打開超鏈接)到別的頁面,Request域的范圍就會失效。
    ServletContext保存的是當前應用所有Servlet共享的信息,也就是說所有人購買的商品信息都會被共享。
    因此Request域和ServletContext信息都不適合保存用戶的個人購物車數據。

    保存會話數據的兩種技術

    Cookie:Cookie是客戶端技術,程序把每個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶著各自的數據去。這樣,web資源處理的就是用戶各自的數據了。
    Session:Session是服務器端技術,利用這個技術,服務器在運行時可以為每一個用戶的瀏覽器創建一個其獨享的session對象,由于session為用戶瀏覽器獨享,所以用戶在訪問服務器的web資源時,可以把各自的數據放在各自的session中,當用戶再去訪問服務器的其它web資源時,其它web資源再從用戶各自的session中取出數據為用戶服務。


    Cookie的響應頭set-cookie:product=1,瀏覽器的內存會保存cookie的內容,再發送請求時,會帶著頭cookie:product=1去訪問。之后累加。
    Session在服務器端開辟一塊空間,分配一個唯一的標識,每次請求響應都帶著唯一的標識,最終結算通過標識找到空間。

    Cookie技術實現的具體流程如下:
    第一步:用戶通過瀏覽器訪問服務器找到Servlet1。

    第二步:Servlet1為剛才用戶的請求設置一個cookie 隨著響應發送到瀏覽器端
    第三步:瀏覽器會將返回來的cookie 進行緩存起來(或持久存儲起來,如果不設置持久化時間的話 默認是緩存在內存中 等瀏覽器退出釋放內存 cookie才會消失)

    第四步:當該瀏覽器的用戶再次訪問時,會將此cookie帶著去請求該服務器(訪問的有效路徑 即帶著cookie的路徑默認是前一部分路徑 例如:假設Servlet的路徑是 /a/b 有效路徑默認就是/a 如果是/a/b/c 有效路徑就是/a/b)



    Cookie快速入門——顯示用戶的上次的訪問時間
    • 判斷用戶是否是第一次訪問
    • 如果是第一次訪問,需要輸出歡迎,并且記錄當前的時間,保存到cookie中,再回寫到瀏覽器端。
    • 如果不是第一次訪問,獲取cookie中的時間,輸出時間,并且記錄當前的時間,保存到cookie中,再回寫到瀏覽器端。
    示例代碼如下:
    Cookie[] cookies = request.getCookies();
    Cookie cookie = findCookie(cookies, "lastVisit");
    
    response.setContentType("text/html;charset=utf-8");
    if (cookie == null) {
    response.getWriter().println("歡迎登錄本網站!");
    }else{
    long lastVisit = Long.parseLong(cookie.getValue());
    Date d = new Date(lastVisit);
    response.getWriter().println("您上次的訪問時間是:"+d.toLocaleString());
    }
    
    Cookie c = new Cookie("lastVisit",System.currentTimeMillis()+"");
    response.addCookie(c);
    

    Cookie API

    javax.servlet.http.Cookie類用于創建一個Cookie,response接口中也定義了一個addCookie方法,它用于在其響應頭中增加一個相應的Set-Cookie頭字段。同樣,request接口中也定義了一個getCookies方法,它用于獲取客戶端提交的Cookie。Cookie類的方法如下:
    public Cookie(String name, String value) cookie的構造方法
    String getName() 獲取cookie的名稱
    String getValue() 獲取cookie的值
    void setMaxAge(int expiry) 設置cookie的有效時間(int 秒)
    使cookie失效:setMaxAge(0) 注意:失效的前提是失效前要設置cookie的有效路徑(和之前設置過的相同,如果之前沒有設置過有效路徑 只要在cookie的默認路徑內也可不用再設置。若之前設置過有效路徑且當前的Servlet在其有效路徑內,要想使其失效則必須在失效前設置重新設置cookie的有效路徑 且必須和之前設置過的相同)
    void setPath(String uri) 設置有效路徑
    默認的有效路徑:
    配置 /last 默認路徑:/day11(該項目的虛擬路徑)
    配置 /servlet/last 默認路徑:/day11/servlet
    void setDomain(String pattern) :設置有效域名
    * www.sina.com.cn
    * sports.sina.com.cn
    * xxx.sina.com.cn
    * 設置有效域名 setDomain(".sian.com.cn");

    * 會話級別的cookie:默認保存到瀏覽器的內存中。
    * 持久的cookie:把cookie保存到磁盤上。通過setMaxAge(int a)進行設置。

    Cookie細節:

    • 一個Cookie只能標識一種信息,它至少含有一個標識該信息的名稱(NAME)和設置(VALUE)。
    • 一個WEB站點可以給一個WEB瀏覽器發送多個Cookie,一個瀏覽器也可以存儲多個WEB站點提供的Cookie
    • 瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制是4KB。
    • 如果創建了一個Cookie,并將他發送到瀏覽器。默認情況下它是一個會話級別的Cookie(即存儲在瀏覽器的內存中),用戶退出瀏覽器后即被刪除。若希望瀏覽器將該cookie存儲在磁盤上,則需要使用maxAge,并給一個以秒為單位的時間。
    • 刪除持久cookie,可以將cookie最大時效設置為0,注意:刪除cookie時,path必須一致,否則不會刪除。

    cookie應用:顯示用戶上次訪問過的商品信息(需求)
    (1)獲取請求參數
    (2)獲取cookie數組,通過指定的名稱(自己指定的)查找cookie
    (3)如果cookie==null,第一次訪問 (如果第一次訪問,創建cookie,回寫到瀏覽器)
    (4)如果cookie!=null,則不是第一次訪問。
    如果不是第一次訪問,說明我的cookie中已經存在id
    判斷,當前的id是否已經存在于cookie中的value
    如果存在,不用操作
    如果不存在,在后面追加(product=1,2)
    (5)重定向到商品頁面。

    session為每個瀏覽器保存數據


    在WEB開發中,服務器可以為每個用戶瀏覽器創建一個會話對象(session對象),注意:一個瀏覽器獨占一個session對象(默認情況下)。因此,在需要保存用戶數據時,服務器程序可以把用戶數據寫到用戶瀏覽器獨占的session中,當用戶使用瀏覽器訪問其他程序時,其他程序可以從用戶的session中取出該用戶的數據,為用戶服務。
    Session和Cookie的主要區別在于:
    • Cookie是把用戶的數據寫給用戶的瀏覽器。
    • Session技術把用戶的數據寫到用戶獨占的Session中(服務器端)
    Session對象由服務器創建,開發人員可以調用request對象的getSession方法得到Session對象。

    Session實現原理:

    (1)瀏覽器A訪問應用中的Servlet1,服務器端可以通過request.getSession() 為瀏覽器A在服務器端開辟一個專屬于瀏覽器A的唯一Session空間,并利用cookie技術向瀏覽器A返回一個cookie- Jsessionid (值唯一)


    (2)當瀏覽器A訪問另一個Servlet2時,會將cookie中的Jsessionid帶著,服務器可以根據唯一的session標識去識別找到那個session空間 進行內容的管理。(也就是一個應用為每個瀏覽器都可以在服務器端開辟一個專屬于每個瀏覽器的session空間)


    (3)另外每個瀏覽器的session的執行過程也時如此


    (4)不管是哪個瀏覽器都能找到與自己對應的Session空間。


    session方法:
    cookie基于客戶端,不安全,并且大小和個數有限制。
    session域對象,范圍一次會話范圍,存個人相關的數據。
    void setAttribute(String name, Object value) 向session域中可以設置任何對象和集合
    Object getAttribute(String name) 從session中根據名稱取出與相應客戶端有關的信息
    String getId() 獲取session的唯一ID
    void invalidate() 銷毀session

    Session案例一——實現購物車功能
    使用Session完成簡單的購物車功能
    接收傳過來的商品id
    使用Map集合代碼購物車(key商品名稱,value商品數量)
    從session中獲取購物車
    如果獲取不到,是第一次,創建Map,存入商品和數量
    如果獲取到,不是第一次,拿到Map,判斷Map中是否包含商品,如果包含取出數量+1,如果不存在,直接存 入。
    把購物車存入到session中
    Session案例二——瀏覽器禁用Cookie后的Session處理
    實驗演示禁用Cookie后servlet共享數據導致的問題。
    解決方案:URL重寫
    response. encodeRedirectURL(java.lang.String url)
    用于對sendRedirect方法后的url地址進行重寫。
    response. encodeURL(java.lang.String url)
    用于對表單action和超鏈接的url地址進行重寫
    附加:
    Session的失效
    Web.xml文件配置session失效時間

    Session案例三——一次性校驗碼驗證登錄
    一次性驗證碼的主要目的就是為了限制人們利用工具軟件來暴力猜測密碼。
    服務器程序接收到表單數據后,首先判斷用戶是否填寫了正確的驗證碼,只有該驗證碼與服務器端保存的驗證碼匹配時,服務器程序才開始正常的表單處理流程。
    密碼猜測工具要逐一嘗試每個密碼的前題條件是先輸入正確的驗證碼,而驗證碼是一次性有效的,這樣基本上就阻斷了密碼猜測工具的自動地處理過程。
    // 判斷驗證碼是否正確
    	String checkcode_session = (String) request.getSession().getAttribute("checkcode_session");
    	request.getSession().removeAttribute("checkcode_session");
    		if (checkcode_session == null || !checkcode_session.equals(checkcode)) {
    			// 驗證碼輸入錯誤
    			// 重定向跳回 login.jsp 無法攜帶信息,轉發可以
    			request.setAttribute("msg", "驗證碼輸入錯誤!");
    			request.getRequestDispatcher("/session/login.jsp").forward(request,
    					response);
    			return;
    		}
    
    		// 判斷用戶名和密碼是否正確 ,假設用戶名和密碼都是admin/admin
    		if ("admin".equals(username) && "admin".equals(password)) {
    			// 登陸成功
    			// 將登陸信息保存session
    			request.getSession().setAttribute("username", username);
    			response.sendRedirect("/day7/session/welcome.jsp");
    		} else {
    			// 登陸失敗
    			request.setAttribute("msg", "用戶名或者密碼錯誤!");
    			request.getRequestDispatcher("/session/login.jsp").forward(request,
    					response);
    		}
    頁面:
    <h2 style="color:red;">${requestScope.msg }</h2>
    

    Servlet的數據訪問范圍

    application Scope servletContext (數據庫連接池,配置, 線程池, 站點訪問次數)
    * 每一個Web應用對應一個ServletContext
    * 存放所有用戶都可以訪問的數據
    session Scope HttpSession (存放與用戶相關數據)
    * 存放每個用戶自己會話過程中的數據
    request Scope HttpServletRequest
    (Servlet處理結果,JSP顯示)
    * 數據存放在request對象中
    * 生成新的請求時,原request存放數據丟失

    注意:request、Session、ServletContext三個域對象的適用范圍
    (1)ServletContext存放的數據,共享于整個web應用中。
    只要服務器不重啟,存放在ServletContext中的數據就一直有效,并且所有用戶都可以訪問ServletContext中存放的數據。因為同一web應用中僅有一個ServletContext,當多用戶訪問時,會有線程問題,ServletContext不是線程安全的,當然我們也可以使用synchronized關鍵字來同步doGet()和doPost() 方法,解決線程問題。
    例如:數據庫連接、當前在線用戶數、系統管理員聯系方式。
    (2)Session是同一用戶在一次會話期間,在web應用的各個資源之間都可以共享的數據范圍。使用Session就不需要像Request那樣通過轉發請求來傳遞數據,當使用鏈接或者新提交Form表單時,原來Session中的數據,對于當前用戶仍然可用。注意:Session中的數據僅對當前用戶可見。
    (3)存放在Request之中的數據存活范圍。
    • 使用HttpServletRequest對象的getRequestDispatcher()方法得到RequestDispatcher對象,并調用該對象的forward()方法或者include()方法時。當前頁面的HttpServletRequest對象中數據可以在目標頁面使用。
    • 當使用鏈接,或者重新提交一個Form時,當前頁面的Request對象就會被銷毀,其中的數據全部丟失,并生成新的請求。



    Demo實例如下:
    項目結構如下所示:


    web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
    	xmlns="http://java.sun.com/xml/ns/javaee" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <display-name></display-name>
      <servlet>
        <servlet-name>LastServlet</servlet-name>
        <servlet-class>cn.itcast.cookie.LastServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>ProductServlet</servlet-name>
        <servlet-class>cn.itcast.cookie.ProductServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>RemoveServlet</servlet-name>
        <servlet-class>cn.itcast.cookie.RemoveServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>CartServlet</servlet-name>
        <servlet-class>cn.itcast.session.CartServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
        <servlet-name>LastServlet</servlet-name>
        <url-pattern>/servlet/last</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>ProductServlet</servlet-name>
        <url-pattern>/product</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>RemoveServlet</servlet-name>
        <url-pattern>/remove</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>CartServlet</servlet-name>
        <url-pattern>/cart</url-pattern>
      </servlet-mapping>	
      
      <!-- 驗證碼 -->
      <servlet>
        <servlet-name>CheckcodeServlet</servlet-name>
        <servlet-class>cn.itcast.session.CheckcodeServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>cn.itcast.session.LoginServlet</servlet-class>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>CheckcodeServlet</servlet-name>
        <url-pattern>/checkcode</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
      </servlet-mapping>
      
      
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    

    1.jsp (演示<%! %>、<%= %>、<% %>)
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	
    <%! 
    	int a = 10;	
    	
    %>	
    	
    <%=a  %>	
    
    <%
    	int b = 100;
    	if(b == 20){
    		
    	}else{
    		
    	}
    %>
    	
    </body>
    </html>

    2.jsp (演示HTML代碼與<% %>結合處理邏輯)
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	
    	
    	<table border="1" width="60%">
    
    <%
    	for(int i=1;i<=10;i++){
    		
    %>
    	<tr>
    	<%
    		for(int j=1;j<=10;j++){
    			
    	%>
    		<td>1</td>
    	<%		
    			
    		}
    	
    	%>
    	</tr>
    <%		
    		
    	}
    
    %>	
    	
    		
    	</table>
    	
    	
    </body>
    </html>
    3.jsp (熟悉EL表達式)
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <%
    	
    	request.setAttribute("aa", "蒼老師");
    	
    %>	
    
    <%= request.getAttribute("aa") %>
    
    ${ aa }
    
    </body>
    </html>



    MyCookieUtil.java (通過指定的名稱查找指定的cookie)
    package cn.itcast.utils;
    
    import javax.servlet.http.Cookie;
    
    /**
     * cookie工具類
     * @author Administrator
     *
     */
    public class MyCookieUtil {
    	
    	/**
    	 * 通過指定名稱查找指定的cookie
    	 * @param cookies
    	 * @param name
    	 * @return
    	 */
    	public static Cookie getCookieByName(Cookie [] cookies,String name){
    		// 如果數組是null
    		if(cookies == null){
    			return null;
    		}else{
    			// 循環遍歷,目的:和name進行匹配,如果匹配成功,返回當前的cookie
    			for (Cookie cookie : cookies) {
    				// 獲取cookie的名稱,和name進行匹配
    				if(cookie.getName().equals(name)){
    					return cookie;
    				}
    			}
    			return null;
    		}
    	}
    	
    }
    LastServlet.java (判斷是否是第一次訪問)
    package cn.itcast.cookie;
    
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import cn.itcast.utils.MyCookieUtil;
    
    /**
     * 記錄上次的訪問時間
     * @author Administrator
     *
     */
    public class LastServlet extends HttpServlet {
    	
    	private static final long serialVersionUID = -5604481158386227221L;
    	
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		/**	
    		 * 	1.獲取所有的cookie,判斷是否是第一次訪問
    		 * 	2.如果是第一次訪問
    		 * 		* 輸出歡迎,記錄當前的時間,回寫到瀏覽器
    		 * 	3.如果不是第一次訪問
    		 * 		* 獲取時間,輸出到瀏覽器,記錄當前的時間,回寫到瀏覽器。		
    		 * 	記錄當前的時間,回寫到瀏覽器。
    		 */
    		// 設置字符中文亂碼問題
    		response.setContentType("text/html;charset=UTF-8");
    		// 獲取所有的cookie
    		Cookie [] cookies = request.getCookies();
    		// 通過指定cookie名稱來查找cookie		Cookie c = new Cookie("last","當前的時間");
    		Cookie cookie = MyCookieUtil.getCookieByName(cookies,"last");
    		// 判斷,如果cookie==null,說明是第一次訪問
    		if(cookie == null){
    			// 輸出歡迎,記錄當前的時間,回寫到瀏覽器
    			response.getWriter().write("<h3>親,歡迎再來哦!!</h3>");
    		}else{
    			// 獲取cookie的值,輸出瀏覽器,記錄當前的時間,回寫到瀏覽器
    			String value = cookie.getValue();
    			// 輸出瀏覽器
    			response.getWriter().write("<h3>親,您又來了,上次的時間是"+value+"</h3>");
    		}
    		// 記錄當前的時間
    		Date date = new Date();
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		String sDate = sdf.format(date);
    		// 回寫到瀏覽器
    		// 使用cookie回寫
    		Cookie c = new Cookie("last", sDate);
    		
    		// 設置有效時間
    		c.setMaxAge(60*60);	// 秒
    		
    		// 設置有效路徑
    		c.setPath("/day11");
    		
    		// 回寫
    		response.addCookie(c);
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    


    再次訪問



    ProductServlet.java (使用Cookie保存訪問過的商品信息)
    package cn.itcast.cookie;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import cn.itcast.utils.MyCookieUtil;
    
    /**
     * 瀏覽記錄后臺
     * @author Administrator
     *
     */
    public class ProductServlet extends HttpServlet {
    
    	private static final long serialVersionUID = -5747737695587699577L;
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		
    		/**	
    		 * 	1.獲取請求參數
    		 * 	2.獲取cookie數組,通過指定的名稱(自己指定)查找cookie
    		 * 	3.如果cookie==null,第一次訪問
    		 * 		* 如果是第一次訪問,創建cookie,回寫瀏覽器
    		 * 	4.如果cookie!=null,不是第一次訪問
    		 * 		* 如果不是第一次訪問,說明我的cookie中已經存在id
    		 * 			* 判斷,當前的id是否已經存在cookie的中value
    		 * 			* 如果存在,不用操作
    		 * 			* 如果不存在,在后面追加(product=1,2)
    		 * 	5.重定向到商品頁面
    		 */
    		
    		// 獲取請求參數 目的:存入到cookie中
    		String id = request.getParameter("id");
    		// 先獲取所有的cookie,查找指定名稱的cookie
    		Cookie [] cookies = request.getCookies();
    		// 查找指定名稱的cookie
    		Cookie cookie = MyCookieUtil.getCookieByName(cookies, "product");
    		// 如果cookie==null,我第一次訪問,創建cookie,回寫
    		if(cookie == null){
    			// 我第一次訪問,創建cookie,回寫
    			Cookie c = new Cookie("product", id);
    			// 設置有效時間	7天
    			c.setMaxAge(7*24*60*60);
    			// 設置有效路徑
    			c.setPath("/");
    			// 回寫
    			response.addCookie(c);
    		}else{
    			// 如果不是第一次訪問
    			// 獲取cookie的value	(value有可能是 1,2,3)
    			String value = cookie.getValue();	// 1,2,3,4,5
    			// 判斷,當前的商品的id是否包含在value中
    			String [] values = value.split(",");
    			if(!checkId(values,id)){
    				// 不包含
    				cookie.setValue(value+","+id);
    				// 設置有效時間	7天
    				cookie.setMaxAge(7*24*60*60);
    				// 設置有效路徑
    				cookie.setPath("/");
    				// 回寫
    				response.addCookie(cookie);
    			}
    		}
    		// 重定向到商品頁面
    		response.sendRedirect("/day11/cookie/productList.jsp");
    	}
    
    	/**
    	 * 判斷,當前的id是否包含在values的數組中
    	 * @param values
    	 * @param id
    	 * @return
    	 */
    	private boolean checkId(String[] values, String id) {
    		for (String s : values) {
    			if(s.equals(id)){
    				return true;
    			}
    		}
    		return false;
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    RemoveServlet.java (請求瀏覽的商品記錄信息,即清除cookie)
    package cn.itcast.cookie;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 清除cookie
     * @author Administrator
     *
     */
    public class RemoveServlet extends HttpServlet {
    	
    	private static final long serialVersionUID = 717641936110777278L;
    	
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		// 獲取cookie
    		// 創建Cookie的名稱product
    		Cookie cookie = new Cookie("product", "");
    		// 設置有效時間
    		cookie.setMaxAge(0);
    		// 設置有效路徑
    		cookie.setPath("/");
    		// 回寫
    		response.addCookie(cookie);
    		// 重定向商品列表頁面
    		response.sendRedirect("/day11/cookie/productList.jsp");
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    

    productList.jsp (顯示商品信息界面)
    <%@page import="cn.itcast.utils.MyCookieUtil"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    	
    	<style type="text/css">
    		.img1{
    			width: 160px;
    			height: 140px;
    		}
    		.img2{
    			width: 80px;
    			height: 70px;
    		}
    	
    	</style>
    
    </head>
    <body>
    	
    	<img class="img1" src="/day11/img/1.jpg"><a href="/day11/product?id=1" >手電筒</a>
    	<img class="img1" src="/day11/img/2.jpg"><a href="/day11/product?id=2" >電話</a>
    	<img class="img1" src="/day11/img/3.jpg"><a href="/day11/product?id=3" >電視</a><br/>
    	<img class="img1" src="/day11/img/4.jpg"><a href="/day11/product?id=4" >冰箱</a>
    	<img class="img1" src="/day11/img/5.jpg"><a href="/day11/product?id=5" >手表</a>
    	<img class="img1" src="/day11/img/6.jpg"><a href="/day11/product?id=6" >電腦</a>
    	
    	<h3>瀏覽記錄</h3>
    	<h3><a href="/day11/remove">清除記錄</a></h3>
    	
    <%
    	// 獲取cookie中的value,1,2,3	循環遍歷,
    	Cookie [] cookies = request.getCookies();
    	// 查找指定名稱的cookie
    	Cookie cookie = MyCookieUtil.getCookieByName(cookies, "product");
    	// 如果cookie不為空,拿到值,遍歷
    	if(cookie != null){
    		// 獲取值	1,2,3
    		String value = cookie.getValue();
    		// 分隔
    		String [] ids = value.split(",");
    		// 循環遍歷,獲取id
    		for(String id : ids){
    			
    %>
    	
    	<img class="img2" src="/day11/img/<%= id %>.jpg"><br/>
    	
    <%
    			
    			
    		}
    	}
    %>	
    	
    </body>
    </html>
    





    關閉瀏覽器打開后 信息仍然存在 (是因為Cookie使用了 setMaxAge方法持久化了一段時間)

    CartServlet.java (Session實現購物車)
    package cn.itcast.session;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * 購物車后臺
     * @author Administrator
     *
     */
    public class CartServlet extends HttpServlet {
    	
    	private static final long serialVersionUID = -4944571720622706932L;
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		
    		/**
    		 * 	1.購物車	Map<String,Integer> cart	把購物車存入session中
    		 * 	2.先獲取購物車,判斷是否是第一次訪問
    		 * 		* 第一次訪問:創建購物車,把商品的名稱和數量加入到購物車,存入session中
    		 * 		* 不是第一次訪問
    		 * 			* 判斷是否包含該商品,通過名稱
    		 * 				* 如果包含,數量+1	存入session中
    		 * 				* 如果不包含,存入購物車,存入session中
    		 * 	3.繼續購物或者結算
    		 */
    		// 獲取參數
    		String id = request.getParameter("id");
    		// 購物車存入商品的名稱和數量
    		String [] names = {"手電筒","冰箱","電視","洗衣機","電腦"};
    		// 把id翻譯名稱
    		int idx = Integer.parseInt(id);
    		// 商品的名稱
    		String name = names[idx - 1];
    		
    		// 從session中獲取購物車,先獲取seesion
    		HttpSession session = request.getSession();
    		// 從session中獲取購物車
    		Map<String, Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
    		// 通過cart進行判斷,是否是第一次訪問
    		if(cart == null){
    			// 創建購物車
    			cart = new HashMap<String, Integer>();
    			// 第一次訪問
    			cart.put(name, 1);
    			// 存入到session中
    			session.setAttribute("cart", cart);
    		}else{
    			// 不是第一次訪問,判斷是否包含該商品
    			if(cart.containsKey(name)){
    				// 包含,取出數量,+1,存入購物車,存入seesion中
    				// 取出
    				Integer count = cart.get(name);
    				count++;
    				// 購物車存入商品
    				cart.put(name, count);
    				// 存入的是購物車
    				session.setAttribute("cart", cart);
    			}else{
    				// 不包含
    				cart.put(name, 1);
    				// 存入到seesion中
    				session.setAttribute("cart", cart);
    			}
    		}
    		// 繼續購物或者結算
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().write("<h3><a href='/day11/session/cartList.jsp'>繼續購物</a> | <a href='/day11/session/pay.jsp'>去結算</a></h3>");
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }

    carList.jsp (顯示購物車界面)
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>購物車</title>
    </head>
    <body>
    	
    	<h3>手電筒<a href="/day11/cart?id=1">加入購物車</a></h3>
    	<h3>冰箱<a href="/day11/cart?id=2">加入購物車</a></h3>
    	<h3>電視<a href="/day11/cart?id=3">加入購物車</a></h3>
    	<h3>洗衣機<a href="/day11/cart?id=4">加入購物車</a></h3>
    	<h3>電腦<a href="/day11/cart?id=5">加入購物車</a></h3>
    	
    </body>
    </html>



    pay.jsp (結算頁面 根據客戶端JSESSIONID獲取在服務器端的對應唯一session中的數據)
    <%@page import="java.util.Set"%>
    <%@page import="java.util.Map"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<h3>結算頁面</h3>
    
    <%	
    	// 獲取購物車,把購物車中的商品信息和數量顯示到頁面上
    	Map<String,Integer> cart = (Map<String,Integer>)request.getSession().getAttribute("cart");
    	// 購物車不為空,循環遍歷
    	if(cart != null){
    		// 循環遍歷
    		Set<String> keys = cart.keySet();
    		// 循環keys,拿到商品的名稱
    		for(String key : keys){
    			
    %>
    		
    		<h3>親,您購買的商品是<%= key %>,數量是<%= cart.get(key) %></h3>
    	
    <%			
    			
    		}
    	}else{
    		
    %>
    		<h3>親,您還沒有購物,請您去<a href="/day11/session/cartList.jsp">購物</a></h3>
    <%		
    		
    	}
    
    %>	
    	
    	
    </body>
    </html>


    CheckcodeServlet.java (生成驗證碼,并把驗證碼信息保存在Session空間內)

    package cn.itcast.session;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * 驗證碼(帶session校驗)
     * @author Administrator
     *
     */
    public class CheckcodeServlet extends HttpServlet {
    	
    	private static final long serialVersionUID = 8496591097127600779L;
    	
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		/**
    		 * 	在內存中生成圖片(紙),沒有設置背景顏色,畫填充的矩形,并且和紙的大小相同,矩形有顏色。
    		 * 	獲取筆的對象(設置顏色,設置字體,畫字符串,畫矩形)
    		 * 	先準備好數據,隨機生成4個字符,把字符畫到紙上
    		 * 	畫干擾線
    		 * 	把內存中的圖片輸出到客戶端上
    		 */
    		int width = 120;
    		int height = 30;
    		// 在內存中生成圖片
    		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    		// 先獲取畫筆對象
    		Graphics2D g = (Graphics2D) image.getGraphics();
    		// 設置灰色
    		g.setColor(Color.GRAY);
    		// 畫填充的矩形
    		g.fillRect(0, 0, width, height);
    		// 設置顏色
    		g.setColor(Color.BLUE);
    		// 畫邊框
    		g.drawRect(0, 0, width-1, height-1);
    		// 準備數據,隨機獲取4個字符
    		// String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
    		String words = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6";
    		
    		// 設置顏色
    		g.setColor(Color.YELLOW);
    		// 設置字體
    		g.setFont(new Font("隸書", Font.BOLD, 20));
    		
    		StringBuffer sb = new StringBuffer();
    		
    		Random random = new Random();
    		int x = 20;
    		int y = 20;
    		for(int i=0;i<4;i++){
    			// void rotate(double theta, double x, double y)  
    			// theta 弧度
    			// hudu = jiaodu * Math.PI / 180;
    			// 獲取正負30之間的角度
    			int jiaodu = random.nextInt(60)-30;
    			double hudu = jiaodu * Math.PI / 180;
    			g.rotate(hudu, x, y);
    			// 獲取下標
    			int index = random.nextInt(words.length());
    			// 返回指定下標位置的字符,隨機獲取下標
    			char ch = words.charAt(index);
    			
    			// 把ch裝起來,存入到session中
    			sb.append(ch);
    			
    			// 寫字符串
    			g.drawString(""+ch, x, y);
    			
    			g.rotate(-hudu, x, y);
    			x += 20;
    		}
    		
    		// 存入session中
    		//HttpSession session = request.getSession();
    		//session.setAttribute("code", sb.toString());
    		
    		request.getSession().setAttribute("code", sb.toString());
    		
    		//String str = (String) session.getAttribute("code");
    		//System.out.println(str);
    		// 設置顏色
    		g.setColor(Color.GREEN);
    		int x1,x2,y1,y2;
    		// 畫干擾線
    		for(int i=0;i<4;i++){
    			x1 = random.nextInt(width);
    			y1 = random.nextInt(height);
    			x2 = random.nextInt(width);
    			y2 = random.nextInt(height);
    			g.drawLine(x1, y1, x2, y2);
    		}
    		
    		// 輸出到客戶端
    		ImageIO.write(image, "jpg", response.getOutputStream());
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    	
    	public static void main(String[] args) {
    		System.out.println("\u9fa5");
    		System.out.println("\u9fa4");
    		System.out.println("\u9fa3");
    		System.out.println("\u9fa2");
    	}
    
    }

    LoginServlet.java (獲取Session中的驗證碼信息 進行對比校驗)
    package cn.itcast.session;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * 校驗驗證碼
     * @author Administrator
     *
     */
    public class LoginServlet extends HttpServlet {
    	
    	private static final long serialVersionUID = 5683537422566655209L;
    	
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		// 解決post請求中文亂碼的問題
    		request.setCharacterEncoding("UTF-8");
    		
    		//HttpSession session = request.getSession();
    		// 獲取session中驗證碼
    		//String code1 = (String) session.getAttribute("code");
    		
    		String code1 = (String) request.getSession().getAttribute("code");
    		
    		System.out.println(code1);
    		
    		// 獲取表單中的驗證碼
    		String code2 = request.getParameter("code");
    		// 是否相同
    		if(code2 != null && code1.equals(code2)){
    			response.getWriter().write("success");
    		}else{
    			// 如果不相同,返回錯誤的信息
    			// 轉發
    			request.setAttribute("msg", "驗證碼輸入錯誤");
    			request.getRequestDispatcher("/session/login.jsp").forward(request, response);
    		}
    		
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }

    login.jsp (驗證登錄界面)
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    ${msg }
    <form action="/day11/login" method="post">
    		<table border="1" width="70%">
    			<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="code" />
    					<img id="imgId" src="/day11/checkcode">
    					<a href="#" onclick="run()">看不清,換一張</a>
    				</td>
    			</tr>
    			<tr>
    				<td colspan="2">
    					<input type="submit" value="登陸"/>
    				</td>
    			</tr>
    		</table>
    	</form>
    </body>
    	<script type="text/javascript">
    		// 看不清,換一張,時間戳
    		function run(){
    			// 獲取圖片
    			var image = document.getElementById("imgId");
    			image.src = "/day11/checkcode?"+new Date().getTime();
    		}
    	
    	</script>
    </html>

    驗證碼錯誤時

    驗證成功時





    版權聲明:本文為iteye_18817原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/iteye_18817/article/details/82678460

    智能推薦

    (JavaWeb)會話跟蹤技術Cookie和Session(重點)

    文章目錄 Cookie和Session 會話 保存會話的兩種技術 Cookie 實現顯示上次訪問時間 Session Session的使用 session實現購物車功能 Cookie和Session 會話 會話:用戶打開一個瀏覽器,點擊了很多超鏈接,訪問多個web資源,關閉瀏覽器,這個過程可以稱之為會話; 有狀態會話:一個同學來過教室,下次再來教室,我們會知道這個同學,曾經來過,稱之為有狀態會話;...

    JavaWeb 之 必須掌握會話技術Cookie和Session, 你知道多少???(七)

      目錄   會話技術 一.Cookie入門 二.案例2:把瀏覽器發回來的cookie在服務器獲取到 三,Cookie原理 四.Cookie使用注意 五.Cookie種類(持久化) 六.Cookie有效路徑 七.Cookie唯一標識 Session 一.簡述&入門案例 二.常見API 三,Session原理 四.Session生命周期 總結: ??????? 會話技術 ...

    會話技術之cookie,session

    會話技術之cookie 這兩種技術有個致命的缺陷就是如果你的設備不支持cookie,那么會話技術就會 全盤失效。 cookie使用最多的場景就是瀏覽器,數據存儲結構是key-value 下面用用戶登錄實例說明cookie技術的實現: view.py: 執行:python manage.py runserver 接下來要做的是通過會話技術將用戶登錄的用戶名傳到個人中心頁面中 啟動服務器: 接下來,在...

    會話技術(Cookie和Session)

    會話技術 什么是會話技術呢?  藝術來源于生活,技術也來源于生活。兩個總統在一起聊天,我們稱作一次會話。兩個人進行會話,有兩個前提:1. 兩個人的語言可以互相溝通 2. 兩個人要有記憶力,可以記住對方所說的內容。  在javaweb中,瀏覽器和服務器之間的通訊也可以看作是兩個人在聊天,為了聊天盡興,所以雙方也要擁有”記憶力”,可以保存之前的聊天狀態。 會...

    會話技術——Cookie和Session

     1、概念 2、Cookie    1)創建和發送 CookieServlet.java 結果是:    2)常見API 注意: 當關閉瀏覽器后,完成一個會話。再重新打開瀏覽器,內存中的Cookie消失。解決辦法是,設置一個方法cookie.setMaxAge();cookie會留在瀏覽器中。...

    猜你喜歡

    hive 導出數據之一列多行,轉為一行多列

    需求:提取數據 說明:原數據是一列多行,需要轉化為一行多列 待查詢表為:temp_05 待查詢數據為: 待查詢數據如圖: 需要提取的數據表頭如下: 預定日期 昨日價格 前天價格 2018-02-01 2018-02-02 2018-02-03 2018-02-04 可用提數 SQL 數據如圖: 以下為嘗試過程 數據如圖: 數據如圖: 數據如圖: 數據如圖:...

    asp.net做一個簡易的聊天室

    要求: 結果: 關鍵代碼: Default.aspx Default.aspx.cs Default2.aspx Default2.aspx.cs Default3.aspx Default3.aspx.cs Default4.aspx...

    動態SQL和多表關聯-筆記

    《動態SQL與多表關聯》筆記 學習目標 能夠使用動態SQL完成SQL拼接 能夠使用resultMap完成多表查詢 能夠使用一對一查詢 能夠使用一對多查詢 (注:多對多其實就是兩個一個多) 映射文件:為什么要resultMap 目標 定義結果映射 使用結果映射 回顧 在mybatis中有2種配置文件: 核心配置文件,如:sqlMapConfig.xml 實體類映射文件,如:UserMapper.xm...

    【OpenGL C++ UE4】獲取模型頂點及面索引數據,并優化存儲結構供UE4繪制

    目錄 一、功能需求 二、成果 三、環境配置 四、詳細步驟 4.1 Max制作三棱錐并處理 4.2 核心代碼 4.2.1 傳入結構體數據 4.2.2 頂點去重、更新索引 4.2.3 輸出本地CSV文件 4.3 UE4繪制 一、功能需求 想必你肯定會問我一個問題,UE4直接導入模型不好么? 哈哈,前提是在做畢設時,導師提供的只有頂點與面索引數據,沒有模型。 下文詳細介紹了畢設開發中的難點,涉...

    解決Pyinstaller打包numpy和pandas庫文件過大問題

    解決Pyinstaller壓縮numpy和pandas庫文件過大問題 文件包類型和網上的方法 Windows下docker的安裝 在docker下實現打包     今天是2021年的第一天,先祝各位小伙伴現年快樂哈。最近因為做了一個項目,需要打包文件,文件中包含了numpy和pandas庫,結果打包出來幾百行的代碼居然要900m,人都傻了,翻遍了全網找解決方...

    精品国产乱码久久久久久蜜桃不卡