Servlet-jsp從入門到精通(一)

web技術(shù)的發(fā)展

  1. 早期的web應(yīng)用主要是靜態(tài)頁面的瀏覽,這些靜態(tài)頁面使用HTML語言編寫,放在服務(wù)器上,用戶使用瀏覽器通過HTTP協(xié)議請求服務(wù)器上的web頁面,服務(wù)器上的web服務(wù)器軟件接受到用戶發(fā)送的請求后,讀取請求URI所標(biāo)識的資源,加上消息包頭發(fā)送給客戶端的瀏覽器,瀏覽器解析響應(yīng)中的HTML數(shù)據(jù),向用戶呈現(xiàn)多姿多彩的HTML頁面。

  2. 但是隨著網(wǎng)絡(luò)的發(fā)展,很多線下業(yè)務(wù)開始向網(wǎng)上發(fā)展,基于Internet的web應(yīng)用也變得越來越復(fù)雜用戶所訪問的資源已不僅僅局限于服務(wù)器硬盤上存放的靜態(tài)網(wǎng)頁,更多的應(yīng)用需要根據(jù)用戶的請求動態(tài)生成網(wǎng)頁信息,復(fù)雜的還需要從數(shù)據(jù)庫中提取信息,經(jīng)過一定的運(yùn)算,生成一個(gè)頁面返回給客戶如何才能實(shí)現(xiàn)?

  3. 利用已經(jīng)實(shí)現(xiàn)HTTP協(xié)議的服務(wù)器端軟件,這些軟件預(yù)先給我們留出了擴(kuò)展的接口,我們只需要按照一定的規(guī)則取提供相應(yīng)的擴(kuò)展功能,當(dāng)這類web服務(wù)器接受到客戶端請求后,判斷請求是否是訪問我們提供的擴(kuò)展功能,如果是,將請求交由我們編寫的程序去處理,處理完成后,程序?qū)⑻幚斫Y(jié)果交回web服務(wù)器軟件,web服務(wù)器軟件拿到結(jié)果后,再將結(jié)果作為相應(yīng)信息返回給客戶端。

  4. 早起使用的web服務(wù)器擴(kuò)展機(jī)制是CGI,它允許用戶調(diào)用web服務(wù)器上的CGI程序,CGI全稱 CommonGateway Interface 公共網(wǎng)關(guān)接口,大多數(shù)的CGI程序使用Perl來編寫,也有通過C,Python或PHP編寫,用戶通過單擊某個(gè)連接或者直接在瀏覽器的地址欄輸入U(xiǎn)RL來訪問CGI程序,web服務(wù)器接受到請求后,發(fā)現(xiàn)這個(gè)請求是給CGI程序的,于是就啟動并運(yùn)行這個(gè)CGI程序,對用于請求進(jìn)行處理。CGI程序解析請求中的CGI數(shù)據(jù),處理數(shù)據(jù),并且產(chǎn)生一個(gè)響應(yīng),這個(gè)響應(yīng)被返回給web服務(wù)器,web服務(wù)器包裝這個(gè)響應(yīng),以HTTP響應(yīng)的形式發(fā)送給Web瀏覽器。但是CGI編寫困難,對用戶請求的響應(yīng)時(shí)間較長以進(jìn)程方式運(yùn)行導(dǎo)致性能受限制。

  5. 1997年,SUN公司推出了Servlet技術(shù),作為java陣營的CGI解決方案,作為對微軟ASP(1996年推出)的推出,SUN公司于1998年推出了JSP技術(shù),允許在HTML頁面中嵌入java腳本代碼,從而實(shí)現(xiàn)動態(tài)網(wǎng)頁的功能。此外,PHP(1994年發(fā)明)技術(shù)也是類似于APS,JSP服務(wù)器端頁面編寫技術(shù)

    • Servlet
      java Servlet(java服務(wù)器小程序)是一個(gè)基于java技術(shù)的web組件,運(yùn)行在服務(wù)器端,由Servlet容器所管理,用于生成動態(tài)的內(nèi)容,Servlet是平臺獨(dú)立的java類,編寫一個(gè)Servlet實(shí)際上就是按照Servlet規(guī)范編寫一個(gè)Java類,Servlet被編譯為平臺獨(dú)立的字節(jié)碼,可以被動態(tài)地加載到支持java技術(shù)的web服務(wù)器中運(yùn)行。

      Servlet容器

      Servlet容器也叫Servlet引擎,是Web服務(wù)器或者應(yīng)用服務(wù)器的一部分,用戶在發(fā)送請求和響應(yīng)之上提供網(wǎng)絡(luò)服務(wù),解碼基于MIME的請求,格式化基于MIME的請求,Servlet不能獨(dú)立運(yùn)行,必須被部署到Servlet容器中,由容器實(shí)例化和調(diào)用Servlet的方法,Servlet容器在Servlet的生命周期內(nèi)包含和管理Servlet

    • 對比CGI

      1. Servlet是單實(shí)例多線程的運(yùn)行方式,每個(gè)請求在一個(gè)獨(dú)立的線程中運(yùn)行,提供服務(wù)的Servlet實(shí)例只有一個(gè)
      2. Servlet 具有可升級性,能響應(yīng)更多的請求,因?yàn)閟ervlet容器使用一個(gè)線程而不是操作系統(tǒng)進(jìn)程,線程占用的資源要小
        3.Servlet使用標(biāo)準(zhǔn)的API,被更多的web服務(wù)器所支持。
        4.Servlet使用java語言編寫,擁有更多的java程序語言的優(yōu)點(diǎn)
        5.Servlet可以訪問java平臺豐富的類庫,使得各種應(yīng)用的開發(fā)更為容易
        6.Servlet容器給Servlet提供額外的功能。
    • Tomcat
      Tomcat是一個(gè)免費(fèi)的開源代碼的Servlet容器,是Apache軟件基金會的一個(gè)頂級項(xiàng)目,由Apache,SUN和其他一些公司及個(gè)人共同開發(fā)而成,由于SUN的參與與支持,最新的Servlet和JSP規(guī)范總是能在Tomcat中得到體現(xiàn)。Tomcat支持Servlet2.5

    • Tomcat的安裝

    • 安裝jdk,并且配置環(huán)境變量 path,CLASSPATH,JAVA_HOME

    • 解壓tomcat即可

    • Tomcat的目錄結(jié)構(gòu)

    • bin 存放啟動和關(guān)閉Tomcat的腳本文件

    • conf 存放Tomcat服務(wù)器的各種配置文件,server.xml web.xml等

    • lib 存放Tomcat服務(wù)器和所有web應(yīng)用程序需要訪問的JAR文件

    • logs 存放Tomcat的日志文件

    • temp 存放Tomcat運(yùn)行時(shí)產(chǎn)生的臨時(shí)文件

    • webapps 當(dāng)發(fā)布web應(yīng)用程序時(shí),通常把Web應(yīng)用程序的目錄及文件放到這個(gè)目錄下

    • work Tomcat將JSP生成的Servlet源文件和字節(jié)碼文件存放到這個(gè)目錄下

Servlet詳解

Servlet API

Servlet接口
  1. init(ServletConfig config)
    在Servlet實(shí)例化之后,Servlet容器會調(diào)用init()方法,來初始化該對象,主要是為了讓servlet對象在處理客戶請求前完成一些初始化工作。例如建立數(shù)據(jù)庫的連接,獲取配置信息等。對于每個(gè)Servlet實(shí)例,init()方法只能被調(diào)用一次。Servlet容器通過config參數(shù)向Servlet傳遞配置信息??梢酝ㄟ^config獲取web應(yīng)用程序的初始化參數(shù),還可以獲取ServletContext對象

  2. service(ServletRequest req,ServletResponse res)
    容器調(diào)用service()方法處理客戶端的請求,在調(diào)用service()方法被容器調(diào)用之前,必須確保Init()方法正確完成,容器會構(gòu)造一個(gè)ServletRequest對象和ServletResponse對象作為參數(shù)傳遞給service()方法。

  3. destroy();
    當(dāng)容器檢測到一個(gè)Servlet對象應(yīng)該從服務(wù)中被移除的時(shí)候,容器會調(diào)用該對象的destory方法,以便讓Servlet對象可以釋放它所使用的資源,保存數(shù)據(jù)到數(shù)據(jù)庫中。

  4. ServletConfig getServletConfig()
    返回容器調(diào)用init()方法時(shí)傳遞給Servlet對象的ServletConfig對象

  5. String getServletInfo()
    返回一個(gè)String類型的字符串,包含了關(guān)于Servlet的信息,例如版權(quán),作者等。

ServletRequest

ServletRequest 對象,用來封裝請求數(shù)據(jù)
  1. Object getAttribute(String name)
    返回以name為名字的屬性的值,如果不存在,返回null
  2. Enumeration getAttributeNames();
    返回請求中所有可用的屬性的名字。返回一個(gè)枚舉集合
  3. void removeAttribute(String name);
    移除請求中名字為name的屬性
  4. void setAttribute(String key,Object val);
    在請求中保存一個(gè)鍵值對。
  5. getCharacterEncoding()
    返回請求正文使用的字符編碼的名字
  6. int getContentLength()
    以字節(jié)為單位,返回請求正文的長度。
  7. String getContentType()
    返回正文的MIME類型
  8. ServletInputStream getInputStream()
  9. BufferedReader getReader()
  10. String getLocalAddr()
    返回接收到請求的網(wǎng)絡(luò)接口的IP地址。
  11. String getRemoteAddr()
    返回發(fā)送請求的客戶端或最后一個(gè)代理服務(wù)器的IP地址
  12. String getRemoteHost()
    返回發(fā)送請求的客戶端或者最后一個(gè)代理服務(wù)器的完整限定名
  13. String getLocalName()
    返回接收到請求的IP接口的主機(jī)名
  14. int getLocalPort()
    返回接收到請求的網(wǎng)絡(luò)接口的IP端口號
  15. int getRemotePort()
    返回發(fā)送請求的客戶端或最后一個(gè)代理服務(wù)器的IP源端口。
  16. String getParameter(String name)
    返回請求中name參數(shù)的值,如果name參數(shù)有多個(gè)值,該方法返回值列表中的第一個(gè)值。如果請求中沒有找到該參數(shù),返回null
  17. Enumeration getParameterNames()
    返回請求中包含的所有的參數(shù)的名字。
  18. String[] getParameterValues(String name);
    返回請求中name參數(shù)所有的值
  19. String getProtocal()
    返回請求使用的協(xié)議的名字和版本 例如: HTTP/1.1
  20. RequestDispatcher getRequestDispatcher(String path)
    返回RequestDispather對象,作為path所定位的資源的封裝。
  21. String getServerName()
    返回請求發(fā)送到服務(wù)器的主機(jī)名
  22. int getServerPort()
    返回請求發(fā)送到服務(wù)器的端口號
  23. setCharacterEncoding(String env)
    覆蓋在請求正文中所使用的字符編碼的名字。
ServletResponse對象,用來封裝響應(yīng)數(shù)據(jù)
  1. flushBuffer() 強(qiáng)制把任何在緩存中的內(nèi)容發(fā)送到客戶端
  2. int getBufferSize() 返回實(shí)際用于響應(yīng)的緩存的大小,如果沒有使用緩存,這個(gè)方法返回0
  3. String getCharacterEncoding()
    返回響應(yīng)中發(fā)送的正文所使用的字符編碼(MIME字符集)
  4. String getContentType()
    返回響應(yīng)中發(fā)送的正文所使用的MIME類型
  5. ServletOutputStream getOutputStream()
  6. PrintWriter getWriter()
  7. boolean isCommitted() 返回一個(gè)布爾值,指示是否已經(jīng)提交了響應(yīng)。
  8. void reset() 清除在緩存中的任何數(shù)據(jù),包括狀態(tài)代碼和消息報(bào)頭。
  9. void resetBuffer() 清除在緩存中的響應(yīng)內(nèi)容,保留狀態(tài)代碼和消息包頭。
  10. void setBufferSize(int size)
    設(shè)置響應(yīng)正文的緩存大小。
  11. void setCharacterEncoding(String charset)
    設(shè)置發(fā)送到客戶端的響應(yīng)的字符編碼
  12. void setContentLength(int len)
    設(shè)置內(nèi)容正文的長度
  13. void setContentType(String type)
    設(shè)置要發(fā)送到客戶端的響應(yīng)的內(nèi)容類型。例如:"text/html;charset=UTF-8"
ServletConfig
  1. Servlet容器使用ServletConfig對象在Servlet初始化期間向它傳遞配置信息,一個(gè)ServletConfig對象。

  2. String getInitParameter(String name);
    返回名字為name的初始化參數(shù)的值,初始化參數(shù)在web.xml配置文件中進(jìn)行配置。

  3. Enumeration getInitParameterNames()
    返回Servlet所有初始化參數(shù)的名字的枚舉集合。

  4. ServletContext getServletContext()
    返回Servlet上下文對象的引用。

  5. String getServletName()
    返回Servlet實(shí)例的名字,這個(gè)名字是web應(yīng)用程序的部署描述符中指定。

  6. 編寫一個(gè)Servlet實(shí)際上就是編寫一個(gè)實(shí)現(xiàn)了javax.servlet.Servlet接口的類。

GenericServlet
  1. 如果要編寫一個(gè)通用的Servlet,只需要從GenericServlet繼承,并且實(shí)現(xiàn)抽象方法service();

      String getInitParameter(String name)
      Enumeration getInitParameterNames();
      ServletContext getServletContext()
      init(ServletConfig config)
    
HttpServlet
  1. 在絕大多數(shù)的網(wǎng)絡(luò)應(yīng)用中,都是客戶端通過HTTP協(xié)議去訪問服務(wù)器端的資源我們編寫的Servlet也主要是應(yīng)用于HTTP協(xié)議的請求和響應(yīng),為了快速開發(fā)應(yīng)用于HTTP協(xié)議的Servlet類,sun公司在javax.servlet.http包中給我們提供了一個(gè)抽象類HttpServlet,它繼承自GenericServlet類,用于創(chuàng)建適合WEB站點(diǎn)的HTTP Servlet

     public void service(ServletRequest req,ServletResponse res);
     protected void service(HttpServletRequest req,HttpServletResponse resp)
       針對HTTP1.1定義的7種請求方法GET,POST,HEAD,PUT,DELETE,TRACE,OPTION,
     HttpServlet提供了7個(gè)處理方法
       doGet(HttpServletRequest req,HttpServletResponse resp)
       doPost(HttpServletRequest req,HttpServletResponse resp)
       ......
    
  2. 當(dāng)容器接受到一個(gè)針對HttpServlet對象的請求時(shí),調(diào)用該對象中的方法順序如下:

    1. 調(diào)用公共的service()方法
    2. 在公共的service()方法中,首先將參數(shù)類型轉(zhuǎn)換為HttpServletRequest和HttpServletResponse,然后調(diào)用保護(hù)的service()方法,將轉(zhuǎn)換后的對象作為參數(shù)傳遞進(jìn)去
    3. 在保護(hù)的service方法中,首先調(diào)用HttpServletRequest對象的getMethod方法,獲取HTTP請求方法的名稱,然后根據(jù)請求方法的類型,調(diào)用相應(yīng)的doXxx()方法
HttpServletRequest

繼承自javax.servlet.servletRequest,在該接口中新增的方法如下:

  • String getContextPath()
    返回請求URI中表示請求上下文的部分,上下文路徑是請求URI的開始部分
  • Cookie[] getCookies()
    返回客戶端在此次請求中發(fā)送的所有的Cookie對象
  • String getHeader(String name)
    返回名字為name的請求報(bào)頭的值
  • Enumeration getHeaderNames()
    返回此次請求中包含的所有的報(bào)頭名字的枚舉集合
  • Enumeration getHeaders(String name)
    返回名字為name的請求報(bào)頭的所有值的枚舉集合
  • String getMethod()
    返回此次請求所使用的HTTP方法的名字
  • String getServletPath()
    返回請求URI中調(diào)用Servlet的部分
  • HttpSession getSession()
    返回和此次請求相關(guān)聯(lián)的Session
  • HttpSession getSession(boolean create)
    返回此次請求相關(guān)聯(lián)的Session,如果沒有給客戶端分配Session,并且create參數(shù)為true,則創(chuàng)建一個(gè)新的Session,如果為false,此次請求沒有一個(gè)有效的HttpSession,返回null
HttpServletResponse

該接口繼承ServletResponse,新增的方法入下

  • addCookie(Cookie cookie)
  • addHeader(String name,String value);
  • boolean containsHeader(String name)
  • encodeRedirectURL(String url)
  • 使用SessionID 對于重定向的url編碼,以便用于sendRedirect()方法中
  • encodeURL(String url) 使用SessionID 指定的url編碼
  • sendRedirect(String location) 發(fā)送一個(gè)臨時(shí)的重定向響應(yīng)到客戶端,讓客戶端訪問新的url

Servlet生命周期

Servlet運(yùn)行在Servlet容器中,其聲明周期由容器來管理,其聲明周期通過javax.servlet.Servlet接口中的init(),service(),destory()方法表示Servlet的生命周期包含了4個(gè)階段

  1. 加載和實(shí)例化
    Servlet容器負(fù)責(zé)加載和實(shí)例化Servlet,當(dāng)Servlet容器啟動時(shí),或者是在容器檢測到這個(gè)Servlet來響應(yīng)第一個(gè)請求時(shí),創(chuàng)建Servlet實(shí)例。
  2. 初始化
    在Servlet實(shí)例化之后,容器將調(diào)用Servlet的init()方法初始化這個(gè)對象。對于每個(gè)Servlet實(shí)例,init()方法只被調(diào)用一次,
  3. 請求處理
    Servlet容器調(diào)用Servlet的service()方法對請求進(jìn)行處理。service執(zhí) 行之前init()方法必須成功執(zhí)行。
  4. 服務(wù)終止
    當(dāng)容器檢測到一個(gè)Servlet實(shí)例應(yīng)該從服務(wù)中被移除的時(shí)候,容器就會調(diào)用實(shí)例的destory()方法。釋放資源。
跳轉(zhuǎn)
RequestDispatcher接口
  1. 該對象由Servlet容器創(chuàng)建,用于封裝一個(gè)由路徑標(biāo)識的服務(wù)器資源。利用該對象可以將請求轉(zhuǎn)發(fā)給其他的Servlet或jsp頁面。

  2. forword(ServletRequest req,ServletResponse resp)
    該方法用于將請求從一個(gè)Servlet傳遞給服務(wù)器上的另外的Servlet,jsp或者h(yuǎn)tml文件,在forword方法調(diào)用之后,之前在響應(yīng)緩存中沒有提交的內(nèi)容將會被自動清除。該方法將請求轉(zhuǎn)發(fā)給其他Servlet,將又被調(diào)用的Servlet負(fù)責(zé)對請求做出響應(yīng),原先Servlet執(zhí)行終止。

  3. include(ServletRequest req,ServletResponse resp)
    該方法用于將請求轉(zhuǎn)發(fā)給其他Servlet,被調(diào)用的Servlet對該請求做出的響應(yīng)將并入原來的響應(yīng)對象中,原先的Servlet還可以繼續(xù)輸出響應(yīng)信息。

  4. forword(),include()屬于內(nèi)部請求,瀏覽器地址不發(fā)生改變,客戶端僅向服務(wù)器端發(fā)送一次請求

sendRedirect()

該方法由HttpServletResponse對象提供,
表示重定向到另外一個(gè)請求中。屬于外部請求。重定向相當(dāng)于重新向服務(wù)器發(fā)送請求,瀏覽器地址發(fā)送改變

serlvet-jsp從入門到精通(二)

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

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,798評論 11 349
  • 0 系列目錄# WEB請求處理 WEB請求處理一:瀏覽器請求發(fā)起處理 WEB請求處理二:Nginx請求反向代理 本...
    七寸知架構(gòu)閱讀 14,244評論 22 189
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,692評論 18 399
  • 簡用論道線下互聯(lián)網(wǎng)▏作者:劉益群 “真是沒生意,現(xiàn)在進(jìn)店的客人比以前少多了……” “剛開業(yè)的那段時(shí)間客人還蠻多的,...
    簡用云閱讀 506評論 0 0

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