JSP Servlet基礎知識(二)



1.    HTML 是靜態的,JSP是動態的,交互式的,而且可由用戶定製。

 

2.    服務器:可能是物理主機(硬件),也可能是Web服務器應用(軟件)。

客戶:指人類用戶,或瀏覽器應用。

Web客戶允許用戶請求服務器上的某個資源,並且向用戶顯示請求結果。

 

3.    服務器和客戶的通信

服務器和客戶之間對話的共同的語言是HTTP

服務器使用HTTP向客戶發送信息。

4.    HTTP

請求:HTTP方法(GetPost),要訪問的頁面,表單參數。

響應:狀態碼,內容類型(文本、圖片、HTML等),內容(具體的HTML、圖片等)。

 

5.    HTTP請求:Get請求和Post請求

Get請求:資源的路徑URL以及所有參數都會包括在請求行中。

    請求行:  GET /select/selectBeer.jsp?color=dark&taste=malty HTTP/1.1

    請求首部:Host: www.wickedlysmart.com

             User-Agent: Mozilla/5.0……

             Accept: text/htmlapplication/xmlapplication./xhtml+xml

text/html;q=0.9

             Accept-Language: en-us en;q=0.5

             Accept-Encoding: gizpdeflate

              Accept-Charset: ISO-8859-1utf;q=0.7*;q=0.7

             Keep-Alive:300

             Connection: keep-alive

    GET請求,沒有體,參數只能放在請求行中,並且會顯示在瀏覽器的輸入地址中,不夠安全。

POST請求:又稱爲“消息體”或“有效負載”,放在消息體中,長度不受限制。

    請求行:POST /advisor/selectBeer.do HTTP/1.1

    請求首部:同上

    消息體:(空行)color=dark&taste=malty

    簡單的超鏈接默認是GET方法,如:<a href=”http://www.baidu.com”>link</a>

    Form表單默認也是GET方法。

    GETHEADPUT是冪等的(注:GETdoGet()不同,GET方法是HTTP的,doGet()Servlet)POST不是冪等的。

 

6.    HTTP響應

包括響應首部和體

首部告訴瀏覽器使用的協議,請求是否成功,以及體中放入內容是什麼類型

    HTTP/1.1 200 OK

    Set-Cookie: jsessionID=adfiifeeni23499v99wernnwerr; Pat=/testEL

    Content-Type: text/html(內容類型響應首部的值稱爲MIME類型,MIME類型告訴瀏覽器要接受的數據是什麼類型,其值與HTTP請求首部中的Accept所列的值相關)

    Content-Length:397

    Date: Wed 19 Nov 2003 03:25:40 GMT

    Server: Apache-Coyote/1.1

    Connection: close

體中包含了讓瀏覽器顯示的具體內容:

    (空行)

     <html>……</html>

 

7.    URL(Uniform Resource Locators)

http://www.smart.com:80/beeradvice/select/beer1.html

協議        服務器     端口          路徑          資源

FTP的端口是 31Telnet23SMTP25Time37POP3110HTTPS443

 

8.    Web服務器不做的兩件事情

a)      動態內容。Web服務器應用只提供靜態頁面,動態內容由Web服務器輔助應用(CGI)來完成。

b)      在服務器上保存數據。Web服務器把這些功能轉給輔助應用進行處理。

 

9.    Web容器

 

Web服務器(Apache)得到一個指向servlet的請求,服務器不是把這個請求直接交給servlet本身,而是交給Web容器(Tomcat),由Web容器調用servlet

Web容器管理和運行servlet,容器知道自己與Web服務器之間的協議,Web容器控制者servlet的生命週期,容器會自動地爲它接收每個servlet請求並創建一個新的線程,Web容器負責把JSP代發翻譯成真正的Java代碼。

利用配置文件(web.xml)將servlet部署到容器

一個完全兼容的J2EE應用服務器必須有一個Web容器和一個EJB容器

 

Tomcat是一個Web容器,而不是一個完整的j2ee應用服務器,因爲Tomcat沒有EJB容器。

 

 

 

10.    JSP-Servlet執行流程

    1) 瀏覽器把請求數據發送給容器

    2) 容器根據URL找到正確的Servlet,並把請求傳遞給這個Servlet

    3) Servlet調用輔助應用尋求幫助

    4) 這個輔助應用返回一個回答,Servlet把這個回答增加到請求對象

    5) Servlet把請求轉發給JSP

    6) JSP 從請求對象得到回答

    7) JSP爲容器生成一個頁面

    8) 容器把這個頁面返回給客戶

 

 

 

 

11.    Servlet的生命週期

 

12.    Servlet的屬性和參數

a)      屬性

有三種類型的屬性,應用上下文(ServletContext)、請求(HttpRequest)和會話(HttpSession)

設置方法: setAttribute(String name,Object value)

獲取方法:getAttribute(String name), 返回類型是Object

上下文(ServletContext)屬性不是線程安全的,因爲每個Servlet都可以訪問。讓上下文屬性線程安全的做法:

同步服務器方法(即對doGet()doPost()方法添加synchronized)

同步服務器方法意味着servlet中一次只能運行一個線程,但是並不能阻止其它servletJSP訪問這個屬性。

同步上下文( synchronized(getServletContext()))

synchronized(getServletContext()){

               getServletContext().setAttribute("foo", "22");

               getServletContext().setAttribute("bar", "42");

}

會話屬性:通常,一個客戶同時只有一個請求,就算多個servlet能在單獨的線程中訪問會話屬性,每個線程都是單獨的請求,所以,這時會話屬性是線程安全的。但是一個用戶同時有多個請求時(用戶同時打開多個瀏覽器去訪問),會話屬性是非線程安全的,通過同步HttpSession來達到線程安全。代碼如下:

           HttpSession session=request.getSession();

           synchronized(session){

               session.setAttribute("foo", "22");

               session.setAttribute("bar", "42");

    }

b)      參數

應用上下文初始化參數、請求參數、servlet初始化參數

設置方法:servlet初始化參數只能在DD中設置

獲取方法:getInitParameter(String name)

 

13.    Servlet接受提交的參數

a)      接受單個參數

String username=request.getParameter(“username”);

b)      接受多個參數

String [] parameters=request.getParameterValues(“sizes”);//sizes可以看做是表單中的複選框,如:

            <form action=”**.do”>

<intput type=checkbox name=sizes value=”1”>1

<intput type=checkbox name=sizes value=”2”>2

<intput type=checkbox name=sizes value=”3”>3

<input type=”submit”>

</from>

 

14.    ServletConfigServletContext

a)      ServletConfig對象

每個servlet都有一個ServletConfig對象,用於向servlet傳遞部署信息。

servlet初始化之前不能使用servlet初始化參數。

ServletConfig構建過程如下:

1)      容器讀取當前servletDD(web.xml),包括servlet初始化參數(<init-param>)

2)      容器爲這個servlet創建(new)一個新的ServletConfig實例

3)      容器爲這個servlet初始化參數創建一個String /值對

4)      容器向ServletConfig提供名/值初始化參數的引用

5)      容器創建(new)serlvet類的實例

6)      容器調用servletinit()方法,傳入ServletConfig的引用

容器初始化一個servlet時,會爲這個servlet創建一個唯一的ServletConfig,容器從DD中讀出servlet初始化參數,並把這些參數交給ServletConfig,然後把ServletConfig傳遞給servletinit()方法。

初始化參數:在web.xml配置文件中的<servlet>標籤中

                   <init-param>

                      <param-name>adminEmail</param-name>

                      <param-value>[email protected]</param-value>

        </init-param>

       servlet中調用:getServletConfig().getInitParameter(“adminEmail”);

b)      ServletContext對象

每個Web應用纔有一個ServletContext,用於訪問Web應用參數。Web應用中的各個servletJSP都能訪問ServletContext

初始化參數:在web.xml配置文件中的<web-app>標籤中<servlet>標籤外

                  <context-param>

                      <param-name>contextname1</param-name>

                      <param-value>contextvalue1</param-value>

           </context-param>

servlet中調用:getServletContext().getInitParameter(“adminEmail”);

           或者   ServletContext context=getServletContext();

                context.getInitParameter(“adminEmail”);

JSP中調用:

 

15.    使用響應

通常,使用響應只是向客戶發回數據,會調用兩個方法:setContentType()getWriter()。當然,還可以使用響應設置其它首部、發送錯誤以及增加cookie

response.setContentType(“application/jar”);

完成I/O

ServletContext ctx=getServletContext();

InputStream is=ctx.getResourceAsStream(“/book.jar”);//必須以“/”開頭,表示Web應用的根。

兩種輸出方式

字符形式:PrintWriter writer=response.getWriter();

         writer.println(“some text and HTML”);

字節流形式: ServletOutputStream out=response.getOutputStream();

            out.write(aByteArray);

16.    請求分派和重定向

a)      請求分派

RequestDispatcher view=request.getRequestDispatcher(“***.jsp”);// JSP 實例化一個請求分派器

view.forward(request response);// 使用請求分派器要求容器準備好 JSP ,並向 JSP 發送請求和響應

b)      重定向

response.sendRedirect(“URL”);

其中 URL 是相對的 URL ,有兩種類型:前面有斜線和沒有斜線

例: 客戶原來的請求是   http://www.wick.com/myApp/cool/bar.do ,請求到達名爲“ bar.do ”的 Servlet 時,該 Servlet 中會基於一個相對的 URL 來調用 sendRedirect() 不帶斜線: sendRedirect(“foo/stuff.html”); 容器會相對於原先的請求 URL 建立完整的 URL ,即   http://www.wick.com/myApp/cool/foo/stuff.html

帶斜線的: sendRedirect(“/foo/stuff.html”); 容器會相對於 Web 應用本身建立完整的 URL ,而不是相對於原來的請求 URL ,即: http://www.wick.com/foo/stuff.html

    請求分派是在服務器端發生,瀏覽器地址上的 URL 沒有改變 ( 相當於被請求的 Servlet 把請求傳遞給服務器上的另一個組件,而客戶並不知道 ) ;重定向是在客戶端進行,用戶會在瀏覽器地址欄中看到新的 URL( 相當於服務器又告訴瀏覽器去訪問另一個 URL)

 

17.    HttpSession

http://www.blogjava.net/cheneyfree/archive/2007/05/26/120168.html

可以跨多個請求保存會話狀態,與一個特定可和的整個會話期間, HttpSession 對象會持久存儲。

在響應中發送一個會話:

HttpSession session=request.getSession();// 等價於 request.getSession(true)

//HttpSession session=request.getSession(false); 返回一個已經存在的會話,如果沒有與此客戶相關聯的會話,返回 null

    Web 容器會自己生成會話 ID 、建立新的 Cookie 對象、把會話 ID 放到 cookie 中、在響應中設置 Cookie set-Cookie )首部。在後續的請求中,容器會從請求中的 cookie 得到會話 ID ,將這個 ID 與一個現有的會話匹配,並把會話與當前請求關聯。

    如果用戶瀏覽器禁止使用 Cookie ,則在客戶的請求首部中就不會含有 ID Cookie 。這時可重寫 URL 讓客戶和容器交換會話 ID 信息。容器總是默認地先使用 cookie ,如果 cookie 不能工作,容器就會求助於 URL 重寫。 URL 重寫是自動的,但是必須對 URL 完成了編碼它才湊效。如:

out.println(“<a href=\””+response.encodeURL(“/beerTest.do”)+”\”>click </a>”)

重新定向時對 URL 的重編碼: response.encodeRedirectURL(“/beerTest.do”);

URL 編碼只與響應有關,不能在請求中和上下文調用這個方法。

 

URL重定向是服務器自動完成的,對開發人員來說是透明的。(經測,iteye使用Cookie保存用戶通行證的,禁用Cookie後,iteye登陸後,無法正常訪問)

 

    實驗步驟:

 

    1.兩個頁面 hello1.jsp,hello2.jsp

Java代碼 複製代碼 收藏代碼
  1. hello1.jsp  
  2.   
  3. <body>  
  4.    <%  
  5.     String num ="100";  
  6.     session.setAttribute("num",num);  
  7.     //String url =response.encodeUrl("hello2.jsp");  
  8.     //String url =("hello2.jsp");      
  9.     %>  
  10.     <a href=<%=url%>>hello2.jsp</a>   
  11.  </body>  
  12.   
  13. hello2.jsp  
  14.   
  15. <body>  
  16.   <%=session.getAttribute("num")%>  
  17. </body>  
hello1.jsp

<body>
   <%
   	String num ="100";
	session.setAttribute("num",num);
	//String url =response.encodeUrl("hello2.jsp");
	//String url =("hello2.jsp");    
	%>
	<a href=<%=url%>>hello2.jsp</a> 
 </body>

hello2.jsp

<body>
  <%=session.getAttribute("num")%>
</body>

    瀏覽器Cookie禁用,

    打開hello1.jsp中的String url=response.encodeUrl("hello2.jsp");註釋

    訪問http://localhost:8080/SessionTest/hello1.jsp,點擊hello2.jsp

    會跳轉至hello2.jsp,瀏覽器地址欄顯示爲:

    http://localhost:8080/SessionTest/hello2.jsp;jsessionid=85227A80E09D4443B0A037576B3270AF

    頁面結果顯示爲 100

 

    關閉hello1.jsp中的String url=response.encodeUrl("hello2.jsp");打開String url="hello2.jsp";註釋

    訪問http://localhost:8080/SessionTest/hello1.jsp,點擊hello2.jsp

    會跳轉至hello2.jsp,瀏覽器地址欄顯示爲:

    http://localhost:8080/SessionTest/hello2.jsp

    頁面結果顯示爲 null

 

    2.  新建測試頁面index.jsp、test.jsp和SessionTestServlet.java

Java代碼 複製代碼 收藏代碼
  1. index.jsp頁面  
  2.   
  3. <body>  
  4.    <a href="servlet/SesstionTest?userName=zzqrj">test1</a>  
  5.  </body>  
  6.   
  7. SessionTestServlet.java  
  8.   
  9. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  10.             throws ServletException, IOException {  
  11.   
  12.         response.setContentType("text/html");  
  13.         PrintWriter out = response.getWriter();  
  14.   
  15.         String userName = request.getParameter("userName");  
  16.         HttpSession session = request.getSession();  
  17.         session.setAttribute("userName", userName);  
  18.         //String url=response.encodeRedirectUrl("../test.jsp");  
  19.         //String url="../test.jsp";  
  20.         System.out.println(url);  
  21.         response.sendRedirect(url);  
  22.         //RequestDispatcher view=request.getRequestDispatcher(url);  
  23.         //view.forward(request, response);  
  24. }  
  25.   
  26. test.jsp  
  27.   
  28. <body>  
  29. <%=session.getAttribute("userName") %>  
  30.    <a href="<%=response.encodeUrl("servlet/SesstionTest") %>">test1</a>  
  31. </body>  
index.jsp頁面

<body>
   <a href="servlet/SesstionTest?userName=zzqrj">test1</a>
 </body>

SessionTestServlet.java

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		String userName = request.getParameter("userName");
		HttpSession session = request.getSession();
		session.setAttribute("userName", userName);
		//String url=response.encodeRedirectUrl("../test.jsp");
		//String url="../test.jsp";
		System.out.println(url);
		response.sendRedirect(url);
		//RequestDispatcher view=request.getRequestDispatcher(url);
		//view.forward(request, response);
}

test.jsp

<body>
<%=session.getAttribute("userName") %>
   <a href="<%=response.encodeUrl("servlet/SesstionTest") %>">test1</a>
</body>

    測試方法同1,結果也同1.

    3. 打開瀏覽器Cookie,分別對1,2中的頁面進行測試

    不管是String url=response.encodeUrl("hello2.jsp");打開或是String url="hello2.jsp";打開,瀏覽器地址欄均不顯示" ;jsessionid=***** "。並且結果頁面總不爲null。

 

18.    刪除會話

a)      超時設置

程序: session.setMaxInactiveInterval(20*60);

// 改變特定會話實例的 session-timeout 值,不會影響應用中其他會話的超時時間。

DD 描述: 相當於在每個會話上調用 setMaxInactiveInterval() 方法

< session-config >

                < session-timeout > 15 </ session-timeout >   單位是分鐘

        </ session-config >

b)      在會話對象上調用 invalidate() : session.invalidate();

c)      應用程序結束

 

19.    Cookie

 

Cookie 的作用

a)         支持會話狀態

b)        可以使用 cookie 在服務器和客戶之間交換名 / 值對

服務器把 cookie 發送給客戶,客戶再在以後的每個請求中把 cookie 發回,當客戶的瀏覽器退出時,會話 cookie 會自動消失,但是可以設置 cookie 在客戶端持久保存

使用 Cookie

1 )可以從 HTTP 請求和響應中得到與 Cookie 相關的首部

2 )利用 ServletAPI 使用 Cookie

        創建新 Cookie    Cookie  cookie=new Cookie(“username”,name);

        設置 cookie 在客戶端存活時間: cookie.setMaxAge(30*60);

        cookie 發送到客戶: response.addCookie(cookie);

        從客戶請求得到 cookie

               Cookie[] cookies=request.getCookies();

               for(int i=0;i<cookies.length;i++){

       Cookie cookie=cookies[i];

       if(cookie.getName().equals(“username”)){out.println(cookie.getValue());}

}

 

20.        會話生命週期

 

21.        Servlet

是一種跨平臺語言的服務器端技術, 採用 Servlet 開發的應用,不用考慮平臺,多線程等讓人頭疼的問題,使得開發人員專注於業務邏輯的實現,大大解放了生產力。

Servlet 中嵌入 HTML 代碼是開發人員的噩夢


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