Servlet 和 JSP 基礎

--Servlet技術是使用Java語言開發的一套組件規範,
    是由一個單獨的線程來處理的。
--組件是對部分功能的實現,不能單獨運行,
    對這些組件進行管理、建立、銷燬的運行環境稱爲容器。
--這些容器有:Tomcat、Weblogic、JBoss等
--Servlet 的實現
    1)實現接口Servlet
    2)實現抽象類GenericServlet
    3)實現抽象類HttpServlet
    -- HttpServlet的父類——>GenericServlet 實現了接口 -->Servlet
>>>>>>>>>>>>1.報錯和解決<<<<<<<<<<<<<<<<<<<<<<
1. 404錯誤產生緣由及解決方法
    --產生緣由:Web服務器(容器)根據請求地址找不到對應資源
>>如下狀況會出現404錯誤
    1)輸入的地址有誤(應用名大小寫不正確,名稱拼寫不正確)
    2)在web.xml文件中<servlet>和<servlet-mapping>中的兩個<servlet-name>不一致
    3)沒有將工程部署到Tomcat的webapps下面
    4)Web工程部署時的結構沒有遵循Servlet的規範
2. 405錯誤產生緣由及解決方法
    --產生緣由:容器找不到service方法來處理請求。
>>如下狀況容器都將視爲沒有找到service()方法
    1)service方法名寫錯,字母順序不對或大小寫錯誤
    2)service方法參數類型與標準不一致,或參數順序與標準不一致。
        必定是先HttpServletRequest,而後是HttpServletResponse類型
    3)service方法異常、返回值類型與標準不一致,
        必定是拋出ServletException、IOException。返回值類型是void。
3. 500錯誤產生緣由及解決方法
    --錯誤緣由:請求的Servlet在執行service方法的過程當中出現了錯誤,
        程序不能繼續運行了
>>如下狀況容器都將視爲500的一種狀況:
    1)Servlet沒有繼承HttpServlet或實現Servlet接口
    2)web.xml文件中的<servlet-class>寫錯,與真正的包名類名不符
    3)service方法中的代碼運行時拋出異常css

>>>>>>>>>>>>>>>>2.HTTP協議<<<<<<<<<<<<<<<<<<<<<<
--HTTP協議是HyperText Transfer Protocol,即超文本傳輸協議 
--由W3C指定的一種應用層協議
--規範瀏覽器和web服務器如何通訊及通訊的數據格式
>>>一次請求一次鏈接,儘可能下降服務器的壓力
1.HTTP如何通訊
    1)創建鏈接
    2)請求數據
    3)響應數據
    4)關閉鏈接
2.數據包格式:
  2.1請求包數據
    --請求行:請求基本的信息
      --請求方式+請求資源路徑+協議類型+版本
    --消息頭:請求數據的描述信息
    --實體內容:請求的數據
  2.2響應包數據
      --狀態行:響應基本的信息
      --協議類型+版本+狀態碼+狀態描述
    --消息頭:響應數據的描述信息
    --實體內容:響應的數據html

>>>>>>>>>>>>>>>>3.請求方式GET和POST<<<<<<<<<<<<<<<<<<<<<<
1.GET
    --使用請求路徑傳參,將參數附加在路徑上發送服務器
    --參數在傳遞過程當中可見,隱私性差
    --請求路徑空間有限,只能攜帶少許參數(<2K)
     >>全部默認的請求都是GET請求
2.POST
    --使用實體內容傳參
    --參數在傳遞過程當中不可見,隱私性好
    --實體內容專門用來傳參,大小沒有限制
    >>在form上增長method="post"時
3.獲取GET和POSt傳到服務器的參數
    --服務器端處理GET和POST請求是沒有分別的
    --使用方法:
        --req.req.getParameter(表單name屬性) 返回字符串
        --req.getParameterValues(表單name屬性) 返回字符串數字組
            --若是同一個name 對應多個值就用此方法
            --即用於獲取表單中一組參數名相同的控件提交的數據組
4.解決亂碼問題
  4.1 解決服務器端亂碼
    --方案1:
        --get/post:讓Serverlet接收亂碼String,
            用ISO8859-1將其還原稱byte,再用UTF-8將其轉成String
            --byte[] bs = user.getBytes("iso8859-1");
            --user = new String(bs,"utf-8");
        --優勢:萬能   --缺點:麻煩
    --方案2:
          get:修改Tomcat的配置文件server.xml,65行左右
          --優勢:簡單
    --方案3:
        post: 在獲取請求參數以前,設置
            --req.setCharacterEncoding("utf-8");
        優勢:簡單
    ◆注:通常採用後面兩種方式
  4.2 解決瀏覽器端亂碼
      --設置發送的編碼規則
          --res.setContentType("text/html;charset=utf-8");
5.表單的action路徑問題
--表單絕對路徑:
    有固定格式:/項目名/Servlet路徑
--表單相對路徑:
    --沒有固定格式,須要寫出當前訪問和目標Servlet之間的相對位置
    --由於打開網頁和訪問Servlet都由瀏覽器實現,
    --站在瀏覽器的角度來講:
        --網頁訪問路徑:/Servlet2/register.html
        --Servlet訪問路徑:/Servlet2/register
        --由於他們是平級,因此相對路徑是registerjava

>>>>>>>>>>>>>>>>4.重定向<<<<<<<<<<<<<<<<<<<<<<
一、重定向:**重要**
>>實用場景
    1)經典實用場景:(如百度搜索)
        --不一樣服務器之間的跳轉
    2)擴展使用場景
        --解決1個項目內,2個獨立組件之間跳轉問題
    3)重定向的通常使用場景
        --增長、修改、刪除後重定向到查詢。
--res.sendRedirect(目標地址);
二、路徑
--指部署代碼的訪問路徑    
--靜態資源(html/css/js/img等)就是文件在Tomcat存儲的位置
--動態資源(servlet)就是Servlet的訪問路徑(網名)
--項目名
    --req.getContextPath();
--網頁名
    --req.getServletPath();
--在項目中的網頁的絕對路徑
    --req.getRequestURI();
--外網訪問全路徑
    --req.getRequestURL();
--在web中
    URL:資源的真名
    URI:資源的名稱
    --URI包含URL
3.Servlet訪問路徑有3種方式:
    不一樣的方式其處理請求的能力不一樣
    1)精確匹配(/abc)
        --只有訪問/abc路徑能處理請求
        --此Servlet只能處理一個請求
    2)通配符(/*)
        -全部的路徑均可以訪問此Servlet
        -此servlet能處理全部請求
    3)後綴(*.hi)
        --全部以hi爲後綴的路徑均可以訪問此Servlet
        --此Servlet能夠處理多個請求
        --不容許以斜線開頭web

>>>>>>>>>>>>>>>>>>servlet特性<<<<<<<<<<<<<<<<<<<
1.servlet生命週期
    1)實例化(new )
    2)初始化(init())
    3)就緒
    4)銷燬(destory())
>>默認第一次訪問Servlet時會建立並初始化它
>>能夠修改爲啓動Tomcat時就建立並初始化它
>>對於某個類型的Servlet來講,第1,2,4步只會執行一次,
    第三步能夠執行屢次,所以某個類型Servlet在tomcat內
    只有一個實例,即單例。sql

2.  servletconfig 和 ServletContext
    --開發servlet時可能須要讀取一些參數
    --能夠本身寫配置文件及工具來設置這些參數
    --也能夠直接使用web.xml作配置文件,
        並使用config和context對象作工具來讀取其參數。
    --每一個servlet就像一個學生,config就像他的tts帳號。
        即config和servlet是一對一的關係,每一個servlet都會有一個config對象。
    --context就是教室,能夠爲全部學生服務,
        即context和servlet是一對多的關係,項目中只有一個context,爲全部的servlet服務。
    config:
    <servlet>
          <servlet-name>login</servlet-name>
          <servlet-class>web.LoginServlet</servlet-class>
          <!-- 給當前Servlet預置一個參數,此參數在調用Servlet.init方法以前,被對應的config對象讀取,一個init-param 
          標籤對應一條數據-->
          <init-param>
              <param-name>maxOnline</param-name>
              <param-value>1000</param-value>
          </init-param>
      </servlet>數據庫

    --ServletConfig cfg = getServletConfig();
    --String maxOnline = cfg.getInitParameter("maxOnline");apache

    --config 典型的使用場景:
        1.假設壓偶做一個網遊,網限制在線人數。
        2.在用戶登陸時判斷是否已經達到了上線maxOnline 
        3.該參數贏是能夠配置的,而且僅僅是在登陸的Servlet中使用,所以使用config便可。
    --context 典型使用場景:
        1.項目中包含不少查詢功能,如查詢員工,部門等
        2.這些查詢功能通常都有分頁
        3.每頁顯示的行數(size)是須要可配置的
        4.因爲該參數多個功能都要公用,因此用context
        --ServletContext ctx = getServletContext();
        --ctx.setAttribute("count", 0);
    --context的特殊用法:
        1.能夠在程序運行的任何階段你用它來存取變量
        2.其存儲的變量能夠在多個Servlet間共用
        案例:統計網站流量(訪問量)
        
3.Servlet線程安全問題
    1.何時會出現線程安全問題
        --多個線程同時修改一份數據時
        --對象、成員變量存儲在堆中,多線程共用
        --局部變量存儲在棧中,每一個線程有本身的棧幀
        >>多我的同時修改對象或成員變量時
    2.如何解決線程安全問題
        --加鎖
        synchronized (this) {
            代碼塊
        }數組

########################### JSP ################################
--JSP(Java Server Page)是Sun公司制定的一種服務器端動態頁面技術的組件規範,
--以「.jsp」爲後綴的文件中既包含HTML靜態標記用於表現頁面,
--也包含特殊的代碼,用於生成動態內容。
---JSP的實現底層是TOMCAT自動生成一個類來實現Servlet接口,將JSP轉換爲java。
-- #JSP是特殊的Servlet#
1.JSP包含三種類型的Java代碼:
    --JSP表達式(方便輸出)
    --JSP小腳本(完成相對較長的邏輯運算)
    --JSP聲明(添加屬性或方法)(通常不使用)
2.JSP表達式:最終會成爲service()方法中使用out.print語句的輸出
    實例:     <%=3+5%>
            <%=add()%>
            <%=xx.getName()%>
            <%=xx.getName()+「abc」%>
    ◆注意:表達式結束不須要寫分號。
3.JSP小腳本:最終會成爲Servlet中Service方法的一部分
    例:
    <table>
    <%
    List<User> allUser = (List<User>)request.getAttribute(「users「);
    for(User u : allUser){
    %>
        <tr>
            <td> <%=u.getId()%>    </td>
            <td> <%=u.getName()%>  </td>
        </tr>
    <%    }    %>
    </table>
4. JSP頁面中的指令
    --語法:<%@ 指令名  屬性=值 %>
    --經常使用指令包含如下三種:page、include、taglib
    4.1 page指令
        --能夠實如今JSP頁面中導入要用到的Java包,
            也能夠對頁面的一些屬性進行設置
        ---例1:
            <%@ page import=「java.util.*,java.sql.*「%>
        ---例2:
            <%@ page contentType=「text/html;charset=utf-8「%>
            <%@ page pageEncoding=「UTF-8「%>
    4.2 include指令
        --主要用於將其餘頁面包含在另外一個頁面之中
        ---例:<%@ include file=「header.html」 %>
    4.3 taglib指令
        --主要用於在JSP中導入JSTL
        --例:<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
5.JSP頁面中的隱含(九個)對象**重要**
    request、
    response、
    out、
    session、
    application(ServletContext)、
    pagecontext、
    page、
    config、
    exception瀏覽器

>>>>>>>>>>>>>>>>>>>>>>>JSP開發要點<<<<<<<<<<<<<<<<<<<<<
1.轉發
  --在Web服務器端處理用戶請求的時候,會有須要多個Web組件配合才能完成的狀況。
      一個Web組件(Servlet/JSP)將未完成的處理經過容器轉交給
      另一個Web組件繼續完成,這個轉交的過程叫作轉發。
    --常見狀況是Servlet負責獲取數據,而後將數據轉交給JSP進行展示。
    實現轉發的步驟:
        步驟一:綁定數據到request對象
            request.setAttribute(String name,Object obj);
        步驟二:得到轉發器
            RequestDispatcher rd = request.getRequestDispatcher(String uri);
        步驟三:實現轉發
            rd.forward(request,response);
    轉發的原理:
    1.請求到達服務器
    2.根據請求信息建立request和response對象
    3.根據請求資源路徑找到對應的Servlet執行處理
    4.Servlet在處理過程當中從數據庫獲取到結果信息
    5.Servlet將結果信息綁定在request對象中
    6.Servlet通知容器將req和res對象轉交給list.jsp頁面繼續執行對請求的響應
    7.list.jsp頁面被調用並執行時從傳遞過來的request對象中獲取綁定的數據
        生成結果頁面
    8.服務器將list.jsp頁面的執行結果返回給客戶端。
2.重定向和轉發的區別
    --重定向:瀏覽器發送請求到容器訪問A,A能夠發送一個狀態碼302和
        一個Location消息頭到瀏覽器,因而瀏覽器會當即向Location發新的請求。
    --轉發:瀏覽器發送請求到容器訪問A,A能夠通知容器去調用B。
        轉發所涉及的各個Web組件會共享同一個request和response對象,
        而重定向不行。
    --說明:當請求到達容器,容器會建立request對象和response對象。
        當響應發送完畢,容器會當即刪除request對象和response對象。
        即,request對象和response對象的生存時間是一次請求與響應期間。
        轉發以後,瀏覽器地址欄的地址不變,重定向會變。
        轉發的地址必須是同一個應用內部某個地址,而重定向沒有這個限制。
        轉發是一件事情未作完,調用另一個組件繼續作;
        而重定向是一件事情已經作完,再作另一件事情。tomcat

########################### EL和JSTL ################################
>>>爲何須要EL和JSTL
    JSP內嵌大量Java代碼,增長了頁面的維護難度,使用簡單的標籤來表現
    複雜的邏輯及簡單的形式表示運算關係就是EL和JSTL出現的緣由。
>>>>> EL表達式
1.Bean屬性
    Bean:一個公共的類,按照固定的方式提供屬性的get/set訪問方式。
    1.實現序列化接口
    2.有get/set方法
2.EL表達式實現方式
    --沒有爲name屬性賦過值,頁面輸出「」,不會輸出null
    1)${對象名.屬性名}
        --${user.name}    
        從pageContext、request、session、application中依次查找綁定名爲「user」的對象,找到後調用「getName」方法,將返回值輸出。
    2)${對象名[「屬性名」]} 其餘與上面相同
    --對於數組屬性的值可使用以下表達式訪問:
        ${user.Array[0]}
3.四個預對象
    --EL表達式在取值的時候,會依次調用pageContext、request、
        session、application的getAttribute()方法
4.指定對象的查找範圍
    --例:${sessionScope.user.name}
    --一旦指定了對象所在的範圍,那麼只會在範圍內查找綁定對象,
        不會在找不到的時候再去其餘區域中查找了。
    --sessionScope的位置還能夠填寫pageScope、requestScope、applicationScope。
5.使用EL表達式獲取請求參數值
    --如下兩種寫法分別等價:
        ${param.username} 與 request.getParameter(「username」);
        ${paramValues.city} 與request.getParameterValues("city");

>>>>> JSTL
1.什麼是JSTL
    Sun 公司 Java 標準規範的 JSTL 由 apache組織負責維護
2.如何使用JSTL
    ①將標籤庫對應的jar包拷貝到WEB-INF/lib目錄下
    ②使用taglib指令在頁面上引入標籤的命名空間和前綴,幫助系統定位對應的類。
    --例:<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3.c 的核心標籤
    1)if標籤
        <%
            User user = new User();
            user.setName("胡蘿蔔");
            user.setGender("f");
            request.setAttribute("user",user);
        %>
           姓名:${user.name}<br/>
        性別:
        <c:if test="${user.gender =='m'}" var="rs" scope="request">男</c:if>
        <c:if test="${!rs}">女</c:if>    
     2)choose標籤
         --使用choose標籤簡化多個if標籤的判斷
         <%
            User user = new User();
            user.setName("胡蘿蔔");
            user.setGender("x");
            request.setAttribute("user",user);
            %>
        性別:
        <c:choose>
            <c:when test="${user.gender == 'm'}">男</c:when>
            <c:when test="${user.gender =='f'}">女</c:when>
            <c:otherwise>未知</c:otherwise>
        </c:choose>
      3)forEach標籤
          --使用forEach標籤完成對集合的遍歷輸出。
          --其中items屬性爲要遍歷的集合,var屬性爲每次取出來的一個對象,
              varStatus指定當前迭代的狀態
          <table>
            <tr>
                <td>序號</td>
                <td>姓名</td>
                <td>年齡</td>
            </tr>
            <c:forEach items="${users}" var="u" varStatus="s">
                <tr>
                    <td>${s.count}</td>
                    <td>${u.name}</td>
                    <td>${u.age}</td>
                </tr>
            </c:forEach>
        </table>

>>>>>自定義標籤
--如何開發自定義標籤
    1.編寫一個繼承自SimpleTagSupport的Java類:
        import javax.servlet.jsp.tagext.SimpleTagSupport;
        public class HelloTag extends SimpleTagSupport{}
    2.重寫該類的doTag方法,在其中添加處理邏輯:
        import javax.servlet.jsp.JspException;
        import javax.servlet.jsp.JspWriter;
        import javax.servlet.jsp.PageContext;
        import javax.servlet.jsp.tagext.SimpleTagSupport;
        public class HelloTag extends SimpleTagSupport{
                private String info;
                private int qty;
                public void setInfo(String info) {
                    this.info = info;
                }
                public void setQty(int qty) {
                    this.qty = qty;
                }
                @Override
                public void doTag() throws JspException, IOException {
                    PageContext ctx =(PageContext)getJspContext();
                    JspWriter out = ctx.getOut();
                    for(int i=0;i< qty;i++){
                        out.println(info+"<br/>");
                    }
                }
            
        }
    3.在WEB-INF下面新建一個tld文件,用於配置標籤說明文件。代碼以下:
        <?xml version="1.0" encoding="UTF-8" ?>
        <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
            http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  
            version="2.0">
        <tlib-version>1.1</tlib-version>
        <short-name>c1</short-name>
        <uri>http://www.tarena.com.cn/mytag</uri>
        <tag>
            <name>hello</name>
            <tag-class>tag.HelloTag</tag-class>
            <body-content>empty</body-content>
            <attribute>
            <name>info</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            </attribute>
            <attribute>
                <name>qty</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
        </taglib>
    4.標籤在頁面中被引用時的代碼以下:
        <%@taglib uri="http://www.tarena.com.cn/mytag" prefix="c1" %>
        //…  …
        <c1:hello info="hello kitty" qty="${1+5}"/>
    5. 標籤的運行原理
        --容器依據JSP頁面中的uri找到tld文件
            依據標籤中的<c1:hello>hello這個名字找到標籤類tag.HelloTag。
            接下來實例化該標籤,同時屬性值賦給參數,調用doTag方法。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ---報錯時使用統一的錯誤頁面
        <!-- 讓tomcat統一處理項目中的異常。有兩種方式,只能使用一個 -->
        <!-- 第一種方式:在tomcat捕獲到某類型異常時,自動轉發到某錯誤頁面 -->
        <error-page>
            <exception-type>java.lang.Exception</exception-type>
            <location>/WEB-INF/error.jsp</location>
        </error-page>
        <!-- 2.在tomcat捕獲到某編號異常時,自動轉發到某錯誤頁面 -->
        <error-page>
            <error-code>500</error-code>
            <location>/WEB-INF/error.jsp</location>    
        </error-page>
        <error-page>
            <error-code>404</error-code>
            <location>/WEB-INF/error.jsp</location>    
        </error-page>
        <error-page>
            <error-code>405</error-code>
            <location>/WEB-INF/error.jsp</location>    
        </error-page>
        <!-- jsp路徑寫成絕對路徑,由於沒法肯定那個請求中報錯。
              另外tomcat直到要轉發的jsp必定在當前項目內,
              它會自動在路徑前面追加項目名,所以此處路徑不要寫項目名 -->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

########################### Cookie和Session ################################
>>cookie和session的用途
    1)通俗的理解
    ---按照以下的規則存儲數據:
        ⑴多個請求能夠共用這樣的數據
        ⑵多個servlet能夠共用這樣的數據
        ⑶每一個瀏覽器單獨存一份數據
    2)專業的理解
    --HTTP是無狀態協議:即一次請求對應一次響應,響應結束後鏈接即斷開,
        同一個用戶的不一樣請求對於服務器端來說並不會認爲這兩個請求有什麼關聯性,
        並不會以此區分不一樣的客戶端
    --cookie和session就是管理狀態,讓服務器記住瀏覽器的
    狀態:用來證實瀏覽器曾經訪問過服務器的數據
>>狀態管理兩種常見模式
    --狀態管理的過程當中重要的是數據的保存,只有存下來的數據才能在屢次交互中起到記錄的做用,
        因此能夠按照管理的數據的存儲方式和位置的不一樣來區分狀態管理的模式。
    --若是將數據存儲在客戶端,每次向服務器端發請求時都將存在客戶端的數據隨着請求發送到服務器端,
        修改後再發回到客戶端保存的這種模式叫作Cookie。
    --若是將數據存儲在服務器端,而且爲這組數據標示一個編號,只將編號發回給客戶端。
        當客戶端向服務器發送請求時只須要將這個編號發過來,
        服務器端按照這個編號找到對應的數據進行管理的這種模式叫作Session——會話。

>>>>>>>>>>>>>>>>>>>> Cookie <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1.建立cookie
    --Cookie  c = new Cookie(String name,String value);
    --response.addCookie( c );
    ---例:
        Cookie c = new Cookie("username","Lisa");        
        Cookie c2 = new Cookie("city","NewYork");
        response.addCookie(c);
        response.addCookie(c2);
2.獲取Cookie
    --Cookie[] request.getCookies();
    ---例:
    Cookie[] cookies =  request.getCookies();
    if(cookies!=null){
        for(Cookie c : cookies){
            String cookieName = c.getName();
            String cookieValue = c.getValue();
        }
    }
3.修改Cookie
    --經過setValue方法將新的數據存入到cookie中,
        而後由response響應對象發回到客戶端,對原有舊值覆蓋後即實現了修改
    --使用setValue方法修改了Cookie的值,可是不發回到客戶端的話,
        也不會實現數值的改變
4.Cookie的生存時間
    --默認是關閉瀏覽器Cookie自動銷燬
    --若是但願關閉瀏覽器後Cookie仍存在,則能夠經過設置過時時間
        使得Cookie存在硬盤上得以保存更長的時間。
    --void setMaxAge(int seconds);
    seconds > 0 :表明Cookie保存在硬盤上的時長
    seconds = 0 : 表明Cookie的生命時長爲如今,而這一刻稍縱即逝,
        因此立刻Cookie就等同於過了生存時間,因此會被當即刪除。
        這也是刪除Cookie的實現方式。
    seconds < 0 :缺省值,瀏覽器會將Cookie保存在內存中。
5.Cookie編碼
    --Cookie做爲在網絡傳輸的一段字符串文本,只能保存合法的ASCII字符,
        若是要保存中文須要將中文變成合法的ASCII字符,即編碼
    --Cookie c = new Cookie("city",URLEncoder.encode("北京","utf-8"));
6.Cookie解碼
    --服務器讀取客戶端通過編碼以後的信息時,要想可以正確顯示須要
        將信息解碼後才能輸出。使用URLDecoder的decode()方法便可
    --URLDecoder.decode(c.getValue(),"utf-8")
7.Cookie的路徑問題
    1)什麼是Cookie的路徑問題
    --客戶端存儲Cookie以後,並非針對同一個應用訪問任何資源時都
        自動發送Cookie到服務器端,而是會進行路徑的判斷。
    --只有符合路徑規範的請求才會發送Cookie到服務器端。
    --客戶端在接受Cookie時會爲該Cookie記錄一個默認路徑,
        這個路徑記錄的是添加這個Cookie的Web組件的路徑。
    --如,當客戶端向 http://localhost:8080/test/file/addCookie.jsp
        發送請求時建立了cookie,那麼該cookie的路徑就是 /test/file.
    2)何時發送Cookie
    --只有當訪問的地址是Cookie的路徑或者其子路徑時,
        瀏覽器才發送Cookie到服務器端。
    --如:Cookie的路徑是/test/file,那麼若是訪問的是/test/file/a.jsp 
        或者 /test/file/b/c.jsp時,都會發送Cookie。
        若是訪問的是 /test/d.jsp,則瀏覽器不會發送Cookie。
    3)如何設置Cookie的路徑
        --設置Cookie的路徑可使用Cookie的API方法,setPath(String uri);
        ---例:
            Cookie c  = new Cookie(「uname」,「jack」);
            c.setPath(「/test」);
            response.addCookie(c);
    4)Cookie的限制
        (1)Cookie因爲存放的位置在客戶端,因此能夠經過修改設置被用戶禁止
        (2)只能保存少許數據,長度是有限制的,通常爲4kb左右
        (3)只能保存字符串,不能保留複雜的對象類型數據
        (4)Cookie安全性很低,很是容易經過截取數據包來獲取
        (5)網絡中傳輸的內容也會增長網絡的傳輸量影響帶寬

>>>>>>>>>>>>>>>>>>>> Session <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1.什麼是Session
    服務器爲不一樣的客戶端在內存中建立了用於保存數據的Session對象,
    並將用於標識該對象的惟一Id發回給與該對象對應的客戶端。
    當瀏覽器再次發送請求時,SessionId也會被髮送過來,
    服務器憑藉這個惟一Id找到與之對應的Session對象。
    在服務器端維護的這些用於保存與不一樣客戶端交互時的數據的對象叫作Session。
2.Session建立
    --瀏覽器首次訪問時,服務器會自動給它建立一個session
    --服務器在建立request後,會讓request引用這個session
3.獲取Session
    --HttpSession session = req.getSession();
4.如何使用Session綁定對象
    --Session做爲服務器端爲各客戶端保存交互數據的一種方式,
        採用name-value對的形式來區分每一組數據
    --void session.setAttribute(String name,Object obj);
    --獲取綁定數據或移除綁定數據
        --void session.getAttribute(String name);
        --void session.removeAttribute(String name);
5.如何刪除Session對象
    --void  invalidate()
    --該方法會使得服務器端與該客戶端對應的Session對象再也不被Session容器管理,
        進入到垃圾回收的狀態
6. Session超時
    1)什麼是Session超時
        --Session會以對象的形式佔用服務器端的內存
        --Web服務器缺省的超時時間設置通常是30分鐘。
        --一旦Session對象存在的時間超過了這個缺省的時間限制則認爲是Session超時,
            Session會失效,不能再繼續訪問
    2)如何修改Session的缺省時間限制
    --設置session超時的時間:服務器每一個一段時間就會檢查用戶的空閒時間,
          若該用戶的空閒時間已經超過了配置的時間,則將它的session銷燬,單位爲:分鐘
          <session-config>
              <session-timeout>10</session-timeout>
          </session-config>
7. Session優缺點
    優勢:
        (1)Session對象的數據保存在服務器安全較高
        (2)可以保存豐富的數據類型
        (3)可以保存更多的數據,Cookie只能保存大約4kb的字符串。
    缺點:
    --Session的安全性是以犧牲服務器資源爲代價的,
        若是用戶量過大,會嚴重影響服務器的性能。
8.瀏覽器禁用Cookie的後果
    --Session對象的查找依靠的是SID,而這個ID保存在客戶端時是以
        Cookie的形式保存的。一旦瀏覽器禁用Cookie,那麼SID沒法保存,
        Session對象將再也不能使用。
9.什麼是URL重寫
    --解決瀏覽器禁用Cookie
    --瀏覽器在訪問服務器的某個地址時,會使用一個改寫過的地址,
        即在原有地址後追加SessionID,這種從新定義URL內容的方式叫作URL重寫。
    --如:原有地址的寫法爲http://localhost:8080/test/some
        重寫後的地址寫法爲http://localhost:8080/test/some;jsessionid=4E113CB3
    --若是是重定向,使用以下代碼代替response.sendRedirect()
        --response.encodeRedirectURL(String url);

########################### 過濾器和監聽器 ################################
>>>>>>>>>>>>>>>>>>>>>>>>> 過濾器 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
--過濾器是Servlet2.3規範之中一種特殊的Web組件,
    能夠做爲Servlet的輔助性插件存在。
---做用:
    --經常使用來作項目中的一些共性的需求
    --如:記錄日誌、過濾敏感詞、權限檢查
    --過濾器會以極低的耦合度來處理這樣的需求
    >>共性的需求:幾乎每一個請求都要作的事情
1.如何編寫過濾器
    1)編寫一個實現了Filter接口的類
        --public class CommentFilter implements Filter{}
    2)實現Filter接口的三個方法,過濾邏輯在doFilter方法中實現
        --Filter接口中共定義了三個方法,分別是init,doFilter,destroy方法。
        --init方法在建立Filter時會被調用,且只調用一次,
            通常在該方法中作一些數據的準備工做,能夠經過傳入的FilterConfig
            參數獲取在web.xml文件中配置提供給過濾器的初始參數。
        --destroy方法只有在銷燬過濾器對象時被調用一次,用於釋放一些資源的操做
        --doFilter方法內編寫過濾器的具體處理邏輯,會被屢次執行.
            --該方法共有三個參數:
                request、response:請求和響應用於獲取數據以及追加數據
                FilterChain:過濾器鏈,負責多過濾器的傳遞。
        --執行FilterChain的doFilter會調用後續的過濾器或者servlet。
             --chain.doFilter(request,response)
                 若調用該方法,則請求繼續,若不調用,則請求中斷
    3)在Web程序中註冊過濾器
     <filter>
          <filter-name>guoLv</filter-name>
          <filter-class>web.GuolvFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>guoLv</filter-name>
          <!-- 聲明此filter過濾過濾那些請求 -->
          <url-pattern>/*</url-pattern>
      </filter-mapping>
    4)把過濾器和Web應用一塊兒打包部署
        --將編譯後的過濾器和其餘Web組件類合在一塊兒,
            連同web.xml文件放進應用程序結構中便可。
2.過濾器的執行流程
    (1)客戶端發來請求
    (2)進入過濾器的doFilter方法中
    (3)在doFilter方法中執行chain.doFilter()方法,則將控制權交到Servlet.service()方法,
    (4)執行service()方法中的業務邏輯
    (5)業務邏輯執行結束後,回到過濾器的doFilter()方法中,執行chain.doFilter()方法後面的代碼
    (6)該部分有代碼就會執行,執行結束後,將response對象返回給客戶端    
    --過濾器對servlet執行先後都有過濾效果
3.過濾器的優先級
    --優先級是web.xml文件中<filter-mapping>的聲明順序來決定的
4.過濾器的生命週期
    1)啓動服務器時,它會建立filter。
    2)關閉服務器時它會銷燬filter
    --服務器只啓動一次,因此filter是單例的
    --每一個filter解決一個業務,他們的調用順序以配置文件的順序爲準
5.初始化參數
    <filter>
        <filter-name>filter1</filter-name>
        <filter-class>web.CommentFilter1</filter-class>
        <!-- 初始化參數 -->
        <init-param>
          <param-name>illegalStr</param-name>
          <param-value>胡蘿蔔</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filter1</filter-name>
        <url-pattern>/comment</url-pattern>
    </filter-mapping>  
6. 讀取初始化參數
    private FilterConfig config;    
    public void init(FilterConfig fc) throws ServletException {
        config = fc;
    }
    public void doFilter(ServletRequest req, 
                        ServletResponse res, FilterChain chain) 
                        throws IOException, ServletException {
        String illegalStr = config.getInitParameter("illegalStr");
        // … …
    }
    public void destroy() {// … …}

>>>>>>>>>>>>>>>>>>>>>>>>> 監聽器 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<     --servlet規範中定義的一種特殊組件,用來監聽servlet容器產生的事件並進行響應的處理。 1.生命週期相關的事件     容器建立或者銷燬request,session,ServletContext時產生的事件。     --如:統計在線人數 2. 綁定數據相關的事件     --調用(request,response,ServletContext)三個對象的         setAttribute,removeAttribute方法時產生的事件。 3.如何編寫監聽器     step1:寫一個java類,實現相應的監聽器接口(共有8個接口)。         要依據監聽的事件類型來選擇相應的監聽器接口,         好比要監聽session對象的建立和銷燬,要實現HttpSessionListener。     step2:在監聽器接口方法中,實現相應的監聽處理邏輯。         好比,session對象被刪除了,將人數減1。     step3:註冊(在web.xml文件中配置便可)。 4.編寫Java類     public class CountListener implements HttpSessionListener{         private int count = 0;         public void sessionCreated(HttpSessionEvent arg0){             System.out.println("sessionCreated…");             count ++;         }         public sessionDestroyed(HttpSessionEvent arg0){             System.out.println("session destroyed…");             count--;         }     } 5.實現處理邏輯     public void sessionCreated(HttpSessionEvent e){         System.out.print("sessionCreated…");         HttpSession session = e.getSession();         ServletContext ctx = session.getServletContext();         ctx.setAttribute("count",count);     } 6.註冊監聽器     <listener>         <listener-class>web.CountListener</listener-class>     </listener> 7.監聽器的應用場景         系統框架級別的代碼常常須要檢測容器中數據或對象的變化,     以一個不受人爲控制因素的觸發爲執行時機,     因此對於須要根據數據變化來作出自動反饋的功能均可以使用到監聽器.

相關文章
相關標籤/搜索