Servlet and JSP

servlet技術(shù)

1. HTTP協(xié)議

http 是一種應(yīng)用層的通信協(xié)議,一般包括了client和server端。clietn端的過程一般由瀏覽器執(zhí)行。服務(wù)器端是HTTP服務(wù)器。http協(xié)議定義客戶端和服務(wù)器端進(jìn)行交互的方式,最主要的是HTTP請求和響應(yīng)的報文格式。
HTTP報文分為三個部分,以請求為例:

  • 請求行
  • 報文頭
  • 報文體

知道了大概的HTTP協(xié)議之后,下面介紹對HTTP報文進(jìn)行處理的服務(wù)端組件---Servlet.

2. servlet

servlet 即 server applet, 所以可以說servlet是運行在服務(wù)端的java程序。 servlet是特殊的java類, 其運行在容器中。其特殊在Servlet中沒有main方法。所以Servlet只能由其他類調(diào)用執(zhí)行。

servlet一個基本的定義如下:servlet就是一個java類,并提供基于請求和響應(yīng)模式的web服務(wù)。 換句話說,其是用Java編寫的服務(wù)器端程序。其主要功能在于交互式地瀏覽和修改數(shù)據(jù),生成動態(tài)Web內(nèi)容。

Servlet沒有main()方法,他們受控于另外的一個JAVA應(yīng)用,這個JAVA應(yīng)用稱為容器。

2.1 servlet和servlet容器

servlet相當(dāng)于真正對用戶請求進(jìn)行處理的組件(類),而容器是對容器是對這些資源進(jìn)行管理的。
其中tomcat就是一種web容器,其他的web容器有.....
容器提供的功能有:

  • 通信支持
    容器使得Servlet能夠輕松的與web服務(wù)器對話,而不用考慮通信細(xì)節(jié),
  • 生命周期管理
    • 容器控制Servlet的加載,初始化,以及銷毀
  • 多線程支持
    • 容器自動的為它接收到的Servlet請求創(chuàng)建一個線程。
  • 聲明安全
    • 使用容器,可以使用xml的方式對應(yīng)用進(jìn)行聲明式部署。
  • JSP支持

2.2工作流程

下面描述一次web請求的工作流程。

  1. 用戶發(fā)送http請求到服務(wù)器端
  2. 服務(wù)器端的web容器接收到請求報文,對其進(jìn)行解析
  3. 生成HttpServletRequest和HttpServletRequest實例
  4. 容器根據(jù)請求中的URL找到相應(yīng)的Servlet, 并為這個請求創(chuàng)建或分配一個線程,并把請求和響應(yīng)對象傳遞給Servlet線程
  5. 容器調(diào)用Servlet的Service()方法。該方法根據(jù)請求的不同類型,調(diào)用doGet方法或者doPost方法。

2.3 接口于實現(xiàn)類

servlet的接口,以及實現(xiàn)的類

2.4 servlet的生命周期

下面是整個的servlet的生命周期 P132

  • 容器加載類,調(diào)Servlet的無參構(gòu)造器,并調(diào)動Servlet的inti()方法,從而初始化Servlet
    • Init方法,在Servlet一生中只調(diào)用一次,往往為Servlet為客戶請求提供服務(wù)前調(diào)用
    • int()方法使得Servlet可以訪問ServletConfig和ServletContext
  • 請求到來,Servlet執(zhí)行service方法
    • 對Servlet的每個請求都在一個單獨的線程中運行,任何特定的Servlet類都只有一個實例。
  • 容器調(diào)用Servlet中的destroy方法結(jié)束Servlet的生命

Get于POST的區(qū)別

總體上說區(qū)別如下:

  • 傳輸方式
    • HTTP header 和HTTP body
    • URL 可見和URL 不可見
  • 設(shè)計目的
    • 獲取數(shù)據(jù) 和發(fā)送數(shù)據(jù)
  • 安全性
    • 高和低。

具體上二者的區(qū)別如下:

  1. POST方法的消息報文擁有報文體,而Get方法的沒有。雖然二者都可以傳送參數(shù),但是Get的參數(shù)被限制到請求行中。
  2. Get方法獲取數(shù)據(jù)時,參數(shù)直接顯示在瀏覽器地址欄中;而POST方法的參數(shù)不會顯示在地址欄中
  3. Get設(shè)計用于獲取數(shù)據(jù),POST設(shè)計用于推送數(shù)據(jù)
  4. Get方法是冪等的,POST方法不是冪等的。

請求和響應(yīng)

請求

請求對應(yīng)著HTTP的請求報文,請求報文由三部分組成:請求行,請求頭部,請求體。
從請求中可以獲得的參數(shù)包含了這三部分的信息。
具體的API可以查看官方文檔。

響應(yīng)

大多數(shù)時候,使用響應(yīng)知識為了向客戶發(fā)送數(shù)據(jù),以下兩個方法較為常見:

setContentType
getWriter

重定向和委托

請求重定向

即通過response對象發(fā)送給瀏覽器一個新的url地址,讓其重新請求。該過程包含了兩次請求,兩次響應(yīng)。
該步驟如下:

  • 客戶像瀏覽器地址鍵入一個URL
  • 請求到達(dá)服務(wù)器/容器
  • Servlet決定這個請求應(yīng)當(dāng)重定向到另一個完全不同的URL
  • Servlet在響應(yīng)上調(diào)用sendRedirect(astring)
  • Http響應(yīng)中含有一個狀態(tài)碼"301", 還有一個Location首部,該值是一個URL。
  • 瀏覽器得到響應(yīng),發(fā)現(xiàn)了“301”狀態(tài)碼,并尋找Location首部
  • 瀏覽器使用該Location中的值重新建立請求,此時瀏覽器地址欄的URL發(fā)生變化
  • 用戶得到新的請求結(jié)果。
    sendRedirect(String address)取一個String作為參數(shù),而不是URL對象。

注意:: address是重定向的路徑,該路徑可以是絕對路徑也可以是相對路徑,因為重定向可以重定向到其他站點,所以使用絕對路徑時,需要寫明web站點的全稱,例如:"/web_project/send_redict".當(dāng)使用相對路徑,默認(rèn)的就是重定向到當(dāng)前的站點的路徑下面。此時只用寫"send_redict".

請求分派/轉(zhuǎn)發(fā)

大致的工作流程如下:

  • 用戶在瀏覽器的地址欄鍵入URL
  • 請求到達(dá)服務(wù)器
  • Servlet決定這個請求應(yīng)該分配給web應(yīng)用的另一部分
  • Servlet調(diào)用如下代碼:
RequestDispatcher view= request.getRequestDispatcher("result.jsp")
view.forward(request, response);
  • 此時Jsp 接管該請求和響應(yīng)
  • 瀏覽器以正常的方式得到響應(yīng),顯示給用戶,瀏覽器的地址欄并沒有變化,所以用戶不知道是由JSP生成的響應(yīng)

上面中的result.jsp是處理該請求的新對象,其一般的是一個地址,其實轉(zhuǎn)發(fā)的路徑,其可以是相對路徑,也可以是絕對路徑,對于絕對路徑(該路徑在servlet-mapping中配置過,所以有相應(yīng)的servlet進(jìn)行處理)。例如上面的代碼同樣可以寫成:

RequestDispatcher view= request.getRequestDispatcher("/forwardExample")
view.forward(request, response);

<servlet-mapping>
    <servlet-name>ServletForwardExample</servlet-name>
<url-pattern>forwardExample</url-pattern>
</servlet-mapping>

請求轉(zhuǎn)發(fā)對象不僅僅可以通過request對象獲得,也可以通過servletContext對象。下面是例子:

rd=this.getServletContext().getNamedDipather("ServletForwardExample") //這里的參數(shù)是servlet的名字,需要在web.xml中配置過的
rd=this.getServletContext().getRequestDispatcher("/forwardExample") //這里只能填寫絕對路徑

注意的是通過ServletContext獲取的話參數(shù)的設(shè)置。

RequestDispatcher 包含兩個方法:forward()和include方法。forward()方法較為常見。

區(qū)別

  • 瀏覽器地址欄變化
    轉(zhuǎn)發(fā)時地址不變化,重定向地址變化
  • 請求范圍
    重定向可以重定向到站外資源,轉(zhuǎn)發(fā)時不行
  • 請求過程
  • 轉(zhuǎn)發(fā)時一次請求轉(zhuǎn)發(fā),重定向是兩次請求,兩次響應(yīng)。

servlet 配置信息

分為兩種配置,局部配置 和全局配置

  • servletConfig針對具體的Servlet的config
  • ServletContext代表該web應(yīng)用的config
    上面的參數(shù)針對之前已知的信息,且因為參數(shù)只是容器啟動或者Servlet初始化調(diào)用才進(jìn)行讀取,構(gòu)造嗎,所以servletConfig,ServletContext中的配置信息在運行期間不變,除非重新啟動,部署。

如果不同的Servlet之間的共享信息不是事先知道的呢? 屬性信息

屬性

屬性就是一個對象,設(shè)置到另外的三個Servlet對象中-ServletContext, HttpServletRequest, HttpSession中去的。

屬性Vs參數(shù)

Paste_Image.png

屬性是可變的,所以就意味著其存在安全你性問題。所以有下面對于servlet的并發(fā)運行的安全問題。

讀取外部資源配置文件信息,三個方法:
參見: http://blog.csdn.net/mr_li13/article/details/48598361
http://blog.csdn.net/u011702171/article/details/50908407

監(jiān)聽器和過濾器

過濾器

  • 過濾請求和響應(yīng)
  • 自定義過濾規(guī)則
  • 用于對用戶請求進(jìn)行預(yù)處理,和對請求響應(yīng)進(jìn)行后處理的web應(yīng)用組件。

常用的場景

  • 用戶認(rèn)證
  • 編解碼處理
  • 數(shù)據(jù)壓縮處理

過濾器生命周期

只會創(chuàng)建一次

監(jiān)聽器

  • 監(jiān)聽事件發(fā)生,在時間發(fā)生前做出相應(yīng)處理的web組件
    分類
  • 監(jiān)聽?wèi)?yīng)用程序環(huán)境Servletcontext
  • 監(jiān)聽用戶請求對象 ServletRequest
  • 監(jiān)聽用戶會話對象Httpsession

監(jiān)聽器的應(yīng)用場景

  • 應(yīng)用統(tǒng)計
  • 任務(wù)觸發(fā)

會話管理

使用場景

  • 記錄用戶偏好
  • 記錄用戶登錄狀態(tài)
  • 瀏覽記錄

原理

客戶端或者服務(wù)器端保存用戶數(shù)據(jù)。因為Http協(xié)議是無狀態(tài)的。

兩種會話管理方式

  • cookie: 會話數(shù)據(jù)保存在客戶端
  • session. 會話數(shù)據(jù)保存在服務(wù)器端

cookie的工作原理

目的:: 因為Http協(xié)議是無狀態(tài)的,所以Cookie被設(shè)計用來保存和識別用戶。
形式

區(qū)別:

cookie 和session 的區(qū)別:

  • cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。

  • cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙
    考慮到安全應(yīng)當(dāng)使用session。

  • session會在一定時間內(nèi)保存在服務(wù)器上。當(dāng)訪問增多,會比較占用你服務(wù)器的性能
    考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。

  • 單個cookie保存的數(shù)據(jù)不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。

  • 生命周期上的不同: cookie 是累計時間的,即到點就失效的, session是間隔性的失效的,比如設(shè)置20分鐘失效,這個時間是從最后一次訪問session的時間開始算的。
    session也可以直接調(diào)用api來使session失效。

web 應(yīng)用程序結(jié)構(gòu)

  • 靜態(tài)文件
  • META-INF 元信息
  • WEB-INF
    • class
    • lib
    • web.xml 部署描述符,描述一個web程序
      首先是個XML文件 ,
      其次是設(shè)置web應(yīng)用程序的組件部署信息
      servlet容器需要支持部署描述符的所有元素

DD配置

映射

<load-on_startup>改變servlet默認(rèn)的初始化時間。

<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<welcome-file-list>
</welcome-file-list>
參考:http://blog.csdn.net/guihaijinfen/article/details/8363839
在web.xml文件中同樣可以配置<mime-mapping>,其可以對制定的文件制定打開方式。
可以參考:http://jxdwuao.iteye.com/blog/1637809

Servlet并發(fā)處理

并發(fā)

特點:

  • 單實例
  • 多線程
  • 線程不安全

servlet線程安全

  • 變量的線程安全
    • 參數(shù)變量本地化
    • 使用同步塊synchronized
  • 屬性的線程安全
    • ServletContext線程不安全
    • HttpSession理論上線程安全
    • ServletRequest線程安全的
  • 避免在Servlet中創(chuàng)建線程
  • 多個Servlet訪問外部對象加鎖

容器啟動組件順序: 監(jiān)聽器,過濾器,servlet

JSP

JSP 中的六種指令

JSP指令

  • 腳本代碼 <% code %>
  • 指令 <%@ Instruction %>
  • 表達(dá)式 <%= %>
  • 聲明 <%! %>
  • 注釋 <%% -- z注釋 -->
    6種指令在生成代碼的不同。與注意事項。

下圖顯示了容器如何處理JSP:

Paste_Image.png

JSP聲明

  • 一個聲明語句可以聲明一個或多個變量,方法,供后面的JAVA代碼使用
  • <% !%>
  • 表達(dá)式元素中可以包含任何符合JAVA語言規(guī)范的表達(dá)式
  • <% = % >

jsp 腳本

  • 腳本程序可以包含任意的JAVA程序

JSP注釋

<% -- 注釋內(nèi)容--%>

JSP指令

主要設(shè)置JSP頁面的屬性

  • page指令
    • 定義頁面的依賴屬性,比如腳本語言,error頁面,緩存需求等
  • include指令
    - 包含其他文件
  • taglib指令

JSP內(nèi)置對象
可以直接使用而不用申請

jsp內(nèi)置對象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容