JavaWeb筆記十一:jsp入門

JSP

1. 什麼是JSP

  JSP即java server pages,它是JavaWeb的動態資源。
 JSP = html + java腳本 + jsp動作標籤(包含EL表達式)

2. JSP中java腳本

 * <% ... %>:代碼段,Java語句
 * <%= ... %>:表達式,只是表達式!表達式的值會被輸出到客戶端
 * <%! ... %>:定義,定義成員!例如例如成員變量,方法等

<%
  int a = 10;//定義變量
%>
<%
  out.println(a);//輸出變量
%>
<%=a%>//輸出變量
<%!
  private String hello = "world";
  public String sayHello() {
    return hello;
  }
%>
<%=sayHello()%>

4. JSP真身

  * JSP也是Servlet
  * JSP會在第一次被請求時編碼成.java,再編碼成.class文件,它其實就是一個Servlet,在處理請求時執行service()方法。

  查看真身可以得到,jsp中有9個對象可以無需創建即可使用,它們就是jsp九大內置對象。

5. JSP註釋

  * <!-- -->,html註釋,不是JSP註釋,它會出現在JSP的真身中,併發送到客戶端,但客戶端瀏覽器不會顯示它。
  * <%-- --%>,JSP註釋,它不會出現在JSP真身中,也就不可能發送到客戶端瀏覽器了。

會話跟蹤

1. 什麼是會話

  * 用戶撥打10086,從服務檯接通後會話開始;
  * 用戶發出話費查詢請求,服務檯響應。這是該會話中的一個請求;
  * 用戶發出套餐變更請求,服務檯響應。這是該會話中的又一個請求;
  * ...
  * 用戶掛斷電話,會話結束。

2. 會話的特性

  * 一個會話中可能包含多個請求;
  * 一個會話中發出請求的用戶是唯一的;

3. JavaWeb會話

  * 從用戶打開本站第一個頁面開始,會話也開始了;
  * 用戶會發出0~n個請求;
  * 用戶關閉瀏覽器會話結束了。

4. 什麼是會話跟蹤技術

  HTTP是無狀態協議,也就是沒有記憶力的協議,每個請求之間無法共享數據。這就無法知道會話什麼時候開始,什麼時候結束,也無法確定發出請求的用戶身份。這說明需要使用額外的手段來跟蹤會話!
  * 在一個會話中共享數據即會話跟蹤技術

Cookie

1. 什麼是Cookie

* Cookie是HTTP協議的規範之一,它是服務器和客戶端之間傳輸的小數據。
* 首先由服務器通過響應頭把Cookie傳輸給客戶端,客戶端會將Cookie保存起來。
* 當客戶端再次請求同一服務器時,客戶端會在請求頭中添加該服務器保存的Cookie,發送給服務器。
* Cookie就是服務器保存在客戶端的數據!
* Cookie就是一個鍵值對!!!

2. Cookie規範

* Cookie通過請求頭和響應頭在服務器與客戶端之間傳輸;
* Cookie大小限制在4KB之內;
* 一臺服務器在一個客戶端最多保存20個Cookie;
* 一個瀏覽器最多可以保存300個Cookie;

雖然Cookie規範是如此,但在今天,瀏覽器廠商的競爭異常激烈,所以多少會超出Cookie規則的限制。但也不會超出過多!

3. Cookie與請求頭和響應頭

* 服務器向客戶端發送Cookie的響應頭爲Set-Cookie,例如:Set-Cookie:cookiename=cookievalue
* 客戶端向服務器發送Cookie的請求頭爲Cookie,例如:Cookie:cookiename=cookievalue

4. Servlet中向客戶端發送Cookie

 Cookie cookie1 = new Cookie("test1", "abcdefg");
 Cookie cookie2 = new Cookie("test2", "ABCDEFG");
 response.addCookie(cookie1);
 response.addCookie(cookie2);

5. Servlet中獲取客戶端發送過來的Cookie

 Cookie[] cs = request.getCookies();
 if(cs != null) {
    for(Cookie c : cs) {
      System.out.println(c.getName() + "=" + c.getValue());
    }
 }

Cookie的細節

1. Cookie的maxAge

  當服務器創建Cookie對象後,可以調用setMaxAge()方法設置Cookie的最大生命。
  * maxAge > 0:表示Cookie在客戶端硬盤上保存的最大時間,單位爲秒;
  * maxAge < 0:表示Cookie不會被瀏覽器保存到硬盤上,而只在瀏覽器內存中存活,一旦客戶端關閉瀏覽器在,那麼Cookie就消失;
  * maxAge == 0:表示刪除Cookie,例如客戶端硬盤已經存在名爲abc的Cookie,如果服務器再向客戶端發送名爲abc,並且maxAge爲0的Cookie,那麼表示刪除客戶端上的名爲abc的Cookie。

2. Cookie的path

  瀏覽器在訪問BServlet時,是否要帶上AServlet保存的Cookie呢?這要看Cookie的path了。
  現有資源如下:
  * http://localhost:8080/day06_2/servlet/AServlet
  * http://localhost:8080/day06_2/servlet/BServlet,保存名爲xxx的Cookie
  * http://loclahost:8080/day06_2/servlet/CServlet,保存名爲yyy的Cookie
  * http://loclahost:8080/day06_2/servlet/user/DServlet, 保存名爲zzz的Cookie

  // 沒有設置Cookie的path
  AServlet {
     Cookie c = new Cookie("xxx", "XXX");
     response.addCookie(c);
  }
  // 設置了Cookie的path爲/day06_2
  CServlet {
     Cookie c = new Cookie("yyy", "YYY");
     c.setPath="/day06_2";
    response.addCookie(c);
  }
  DServlet {
    Cookie c = new Cookie("zzz", "ZZZ");
    resposne.addCookie(c);
  }

  
  在BServlet中保存的Cookie沒有設置path,那麼它的path默認爲當前BServlet的所在路徑,即“/day06_2/servlet”。
  在CServlet中保存的Cookie設置了path爲/day06_2。
  在DServlet中保存的Cookie沒有設置path,那麼它的path默認爲DServlet的所在路徑,即“day06_2/servlet/user”


  當訪問AServlet時,是否要帶上xxx這個Cookie呢?因爲AServlet的訪問路徑爲/day06_2/servlet/BServlet,它包含了xxx的path,即/day06_2/servlet,所以需要帶上。

  當訪問AServlet時,是否要帶上yyy這個Cookie呢?因爲AServlet的訪問路徑爲/day06_2/servlet/BServlet,它包含了xxx的path,即/day06_2,所以需要帶上。

  當訪問AServlet時,是否要帶上zzz這個Cookie呢?因爲AServlet的訪問路徑爲/day06_2/servlet/BServlet,它不包含zzz的path,即/day06_2/servlet/user,所以不會帶上。

3. Cookie的domain

  Cookie的path是在同一主機中指定共享Cookie,如果主機不同那麼就一定不能共享Cookie,無論path是什麼。
  如果希望不同的二級域名中可以共享Cookie,那麼就要設置Cookie的domain了。
  例如:news.baidu.com、tieba.baidu.com、zhidao.baidu.com,它們的域名不同,但百度希望它們之間可以共享Cookie,那麼就要設置domain了。

  1). 設置Cookie的path爲“/”,例如:cookie.setPath("/");
  2). 設置Cookie的domain,例如:cookie.setDomain(".baidu.com"),其中domain中沒有指定域名前綴!

  在news.baidu.com主機中的某個項目中保存了Cookie
  在tieba.baidu.com主機中某個項目中獲取Cookie

  當然這需要配置兩個虛擬主機才行。

4. Cookie保存中文

  Cookie的name和value都是不能保存中文的,但可以先把中文轉換成URL編碼,然後在保存到Cookie的name和value中。
  String name = "姓名";
  String value = "張三";
  name = URLEncoder.encode(name, "utf-8");
  value = URLEncoder.encode(value, "utf-8");

  Cookie c = new Cookie(name, value);
  response.addCookie(c);

  在獲取Cookie時,再使用URL解碼即可。
  Cookie[] cs = request.getCookies();
  if(cs != null) {
    for(Cookie c : cs) {
      String name = URLDecoder.decode(c.getName(), "utf-8");
      String value = URLDecoder.decode(c.getValue(), "utf-8");
      System.out.println(name + "=" + value);
    }
  }

HttpSession

在JavaWeb中提供了HttpSession類,用來表示http會話。

1. 獲取HttpSession

HttpSession session = request.getSession();
HttpSession session = request.getSession(false);

2. 域功能

  session是域對象,所以有setAttribute()和getAttribute()等方法
  服務器會爲每個會話創建一個session對象,所以session中的數據可供當前會話中所有servlet共享。

3. 登錄案例

  請求功能:
  1. 如果登錄功能,在session中保存user對象
  2. 訪問index1.jsp,查看session中是否存在user對象,如果存在,說明已經登錄過。
  3. 訪問index2.jsp,查看session中是否存在user對象,如果存在,說明已經登錄過。
  如果關閉了瀏覽器,那麼會話結束,再打開瀏覽器就開始了一個新會話,那麼直接訪問index1.jsp或index2.jsp時,session是新的,沒有保存user對象,那麼表示還沒有登錄。

4. session的原理

  session是依賴Cookie實現的。
  session是服務器端對象
  當用戶第一次使用session時(表示第一次請求服務器),服務器會創建session,並創建一個Cookie,在Cookie中保存了session的id,發送給客戶端。這樣客戶端就有了自己session的id了。但這個Cookie只在瀏覽器內存中存在,也就是說,在關閉瀏覽器窗口後,Cookie就會丟失,也就丟失了sessionId。
  當用戶第二次訪問服務器時,會在請求中把保存了sessionId的Cookie發送給服務器,服務器通過sessionId查找session對象,然後給使用。也就是說,只要瀏覽器容器不關閉,無論訪問服務器多少次,使用的都是同一個session對象。這樣也就可以讓多個請求共享同一個session了。
  當用戶關閉了瀏覽器窗口後,再打開瀏覽器訪問服務器,這時請求中沒有了sessionId,那麼服務器會創建一個session,再把sessionId通過Cookie保存到瀏覽器中,也是一個新的會話開始了。原來的session會因爲長時間無法訪問而失效。
  當用戶打開某個服務器頁面長時間沒動作時,這樣session會超時失效,當用戶再有活動時,服務器通過用戶提供的sessionId已經找不到session對象了,那麼服務器還是會創建一個新的session對象,再把新的sessionId保存到客戶端。這也是一個新的會話開始了。

  設置session超時時間
  web.xml文件中配置如下:
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

5. session與瀏覽器

 session對象是保存在服務器端的,而sessionId是通過Cookie保存在客戶端的。
 因爲Cookie不能在多個瀏覽器中共享,所以session也不能在多個瀏覽器中共享。也就是說,使用IE登錄後,再使用FireFox訪問服務器還是沒有登錄的狀態。

 而且同時打開多個相同瀏覽器的窗口,是在使用同一session。如果你使用的是老瀏覽器,例如IE6,那麼就會每個窗口一個session。

6. session的API

 * String getId():獲取sessionId;
 * int getMaxInactiveInterval():獲取session可以的最大不活動時間(秒),默認爲30分鐘。當session在30分鐘內沒有使用,那麼Tomcat會在session池中移除這個session;
 * void setMaxInactiveInterval(int interval):設置session允許的最大不活動時間(秒),如果設置爲1秒,那麼只要session在1秒內不被使用,那麼session就會被移除;
 * long getCreationTime():返回session的創建時間,返回值爲當前時間的毫秒值;
 * long getLastAccessedTime():返回session的最後活動時間,返回值爲當前時間的毫秒值;
 * void invalidate():讓session失效!調用這個方法會被session失效,當session失效後,客戶端再次請求,服務器會給客戶端創建一個新的session,並在響應中給客戶端新session的sessionId;
 * boolean isNew():查看session是否爲新。當客戶端第一次請求時,服務器爲客戶端創建session,但這時服務器還沒有響應客戶端,也就是還沒有把sessionId響應給客戶端時,這時session的狀態爲新。

7. URL重寫

 session依賴Cookie,這是因爲服務器需要把sessionId保存到客戶端。如果用戶的瀏覽器關閉了Cookie功能,那麼session不能使用了!
 還可以在瀏覽器關閉了Cookie後使用URL重寫的方法保存sessionId,這需要在每個URL後面都加上sessionId!這樣用戶的請求中就包含了sessionId,服務器就可以通過sessionId找到對應的session對象了。
  使用response.encodeURL()方法對URL進行編碼,這樣URL中會智能的添加sessionId。
 當瀏覽器支持cookie時,response.encodeURL()方法不會在URL後追加sessionId
  當瀏覽器不支持cookie時,response.encodeURL()方法會在URL後追加sessionId
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章