Servlet快速入門

一、概述

Servlet(Server Applet)豁护,全稱Java Servlet哼凯,是用Java編寫的服務(wù)器端程序。主要功能在于交互式地瀏覽和修改數(shù)據(jù)择镇,生成動態(tài)Web內(nèi)容挡逼。

狹義的Servlet是指Java語言實現(xiàn)的一個接口;廣義的Servlet是指任何實現(xiàn)了這個Servlet接口的類腻豌。一般情況下將Servlet理解為后者家坎。

Servlet運(yùn)行于支持Java的應(yīng)用服務(wù)器中,原理上Servlet可以響應(yīng)任何類型的請求吝梅,但絕大多數(shù)情況下Servlet只用來擴(kuò)展基于HTTP協(xié)議的Web服務(wù)器虱疏。

提供了Servlet功能的服務(wù)器,叫做Servlet容器苏携。Servlet必須部署在Servlet容器中才能使用做瞪。常見的容器包括:Tomcat、WebLogic等右冻。

二装蓬、工作流程

  1. 客戶端發(fā)送請求到服務(wù)器。
  2. 根據(jù)web.xml文件的配置纱扭,查找url對應(yīng)的Servlet類牍帚。
  3. 服務(wù)器啟動并調(diào)用Servlet,Servlet根據(jù)客戶端請求生成響應(yīng)內(nèi)容并將其傳給服務(wù)器乳蛾。
  4. 服務(wù)器將響應(yīng)返回給客戶端暗赶。

三鄙币、生命周期

Servlet沒有main()方法,不能獨立運(yùn)行蹂随,由Servlet引擎控制和調(diào)度十嘿。

針對客戶端的多次Servlet請求,通常服務(wù)器只會在第一次請求的時候創(chuàng)建一個Servlet實例對象岳锁,并駐留在內(nèi)存中绩衷,直到Web容器退出時,該實例對象才會被銷毀浸锨。

  1. Web容器調(diào)用init()方法初始化Servlet唇聘。該方法在Servlet實例的生命周期里只調(diào)用一次版姑≈眩可以傳遞一個實現(xiàn)ServletConfig接口的對象給它,這個對象使Servlet能夠讀取web.xml文件里使用<init-param>標(biāo)簽定義的初始參數(shù)剥险。
  2. 調(diào)用service()方法處理不同類型的請求聪蘸。該方法使用HttpServletRequest請求對象和HttpServletResponse響應(yīng)對象作為參數(shù)。根據(jù)請求的方式調(diào)用適當(dāng)?shù)姆椒▉硖幚碚埱螅ㄈ鏳oGet或doPost等)表制。
  3. 調(diào)用destroy()方法銷毀Servlet健爬。該方法在Servlet實例的生命周期里只調(diào)用一次。

四么介、體系結(jié)構(gòu)

Servlet編程需要用到j(luò)avax.servlet和javax.servlet.http兩個包下面的類和接口娜遵。接口javax.servlet.servlet定義了所有servlet必須實現(xiàn)的方法。所有servlet程序必須實現(xiàn)該接口或繼承實現(xiàn)了該接口的類壤短。為了實現(xiàn)該接口设拟,可以繼承javax.servlet.GenericServlet或javax.servlet.http.HttpServlet類。

接口javax.servlet.servlet定義的方法:

public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletHttpRequest req, ServletHttpResponse res)
public void destroy()

主要的類和接口包括:

javax.servlet.ServletConfig
javax.servlet.ServletException
javax.servlet.ServletContext
javax.servlet.GenericServlet
javax.servlet.http.HttpServlet
javax.servlet.http.HttpServletRequest
javax.servlet.http.HttpServletResponse
javax.servlet.http.HttpSession
javax.servlet.http.Cookie

五久脯、請求和響應(yīng)

Web服務(wù)器會對收到的每一次客戶端http請求纳胧,分別創(chuàng)建一個用于代表請求的request對象和代表響應(yīng)的response對象。要獲取客戶端提交的數(shù)據(jù)需要通過request帘撰,要想容器輸出數(shù)據(jù)需要通過response跑慕。

1、請求

HttpServletRequest對象代表客戶端的請求摧找,當(dāng)客戶端通過HTTP協(xié)議訪問服務(wù)器時核行,HTTP請求頭中的所有信息都封裝在此對象中。為了獲取請求參數(shù)蹬耘,需要調(diào)用HttpServletRequest對象的getParameter()方法芝雪,并且將要獲取的輸入?yún)?shù)的id傳遞給該方法。

2婆赠、響應(yīng)

HttpServletResponse對象代表服務(wù)器的響應(yīng)绵脯,該對象封裝了向客戶端發(fā)送數(shù)據(jù)佳励、發(fā)送響應(yīng)頭、發(fā)送響應(yīng)狀態(tài)碼的方法蛆挫。為了發(fā)送內(nèi)容給客戶端赃承,需要使用從HttpServletResponse對象獲取的PrintWriter對象,任何寫到這個對象的內(nèi)容都會被寫進(jìn)outputstream里悴侵,并會把內(nèi)容發(fā)送到客戶端瞧剖。

為了獲取配置文件中的初始化參數(shù),可以調(diào)用getServletConfig().getInitParameter("name")方法可免。

六抓于、配置

進(jìn)行Servlet的配置有兩種方法:

  • 通過web.xml配置文件
  • 使用注解@WebServlet(name=””, urlPatterns=””)

1、web.xml

雖然web.xml對于web工程來說并不是必須的浇借,為了能夠輕松應(yīng)對可能面對的各種復(fù)雜情況捉撮,使用web.xml進(jìn)行工程配置還是很有必要的。通常是創(chuàng)建在工程的WEB-INF目錄下妇垢,用來配置歡迎頁巾遭、servlet、listener闯估、filter等信息灼舍。

web.xml中能夠使用的標(biāo)簽,是由模式文件定義的涨薪,而模式文件則由Sun公司(現(xiàn)已被Oracle收購)來定義悬赏。在每個web.xml文件的根元素<web-app>中揭斧,必須標(biāo)明使用哪個模式文件鸠儿。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
        http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
     version="3.1">

訪問網(wǎng)站時涛贯,默認(rèn)顯示的第一個頁面叫做歡迎頁面,一般情況下由首頁做為歡迎頁面光督⊙艟啵可以設(shè)置多個歡迎頁面,按照設(shè)置順序依次查找结借。如果頁面存在就顯示該頁面筐摘,不再繼續(xù)查找。如果頁面不存在船老,則返回404錯誤咖熟。

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

可以通過異常類型或錯誤碼來設(shè)置錯誤處理頁面。

<error-page>
    <exception-type>java.lang.Exception<exception-type>
    <location>/exception.jsp<location>
</error-page>

<error-page>
    <error-code>404</error-code>
    <location>/error.jsp</location>
</error-page>

可以設(shè)置servlet以及servlet與URL的映射柳畔。servlet的定義必須在servlet映射之前進(jìn)行設(shè)置馍管。

<servlet>
    <servlet-name>test-servlet</servlet-name>
    <servlet-class>com.demo.TestServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>test-servlet</servlet-name>
    <url-pattern>/test</url-pattern>
</servlet-mapping>

還可以設(shè)置會話的失效時間,以分鐘為單位薪韩。

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

web.xml中元素的加載順序:<context-param> -> <listener> -> <filter> -> <servlet>确沸。同類型元素之間根據(jù)mapping的順序進(jìn)行調(diào)用捌锭。

還有一些其他常用的元素:

  • <display-name>定義web應(yīng)用的名稱
  • <description>聲明web應(yīng)用的描述信息
  • <context-param>聲明應(yīng)用范圍內(nèi)的初始化參數(shù)

2、注解@WebServlet

在Java5以后罗捎,提供了資源注入(即注解)的方式观谦,可以直接在servlet類注解配置信息,而不需要通過web.xml進(jìn)行配置桨菜。

@WebServlet(urlPatterns={"/test"})
public class TestServlet extends HttpServlet {
    ......
}

七豁状、監(jiān)聽器

為了創(chuàng)建一個基于容器事件的監(jiān)聽器,必須創(chuàng)建一個實現(xiàn)ServletContextListener接口的類倒得。該類必須實現(xiàn)contextInitialized()和contextDestroyed()兩個方法泻红。這兩個方法都需要ServletContextEvent作為參數(shù),并且在每次初始化或關(guān)閉容器時都會被自動調(diào)用霞掺。

注冊監(jiān)聽器除了通過web.xml和使用@WebListener注解外谊路,還可以使用ServletContext里定義的addListener()方法。

常用的監(jiān)聽器類:

javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.ServletContextListener
javax.servlet.ServletContextAttributeListener
javax.servlet.HttpSessionListener
javax.servlet.HttpSessionAttributeListener

八根悼、過濾器

Web過濾器在給定的URL被訪問時凶异,對請求進(jìn)行預(yù)處理,會在Servlet調(diào)用前被調(diào)用挤巡。很多情況下,使用過濾器是很有用的酷麦,如執(zhí)行日志矿卑、驗證、或其他不需要與用戶交互的后臺服務(wù)等沃饶。

過濾器必須實現(xiàn)javax.servlet.Filter接口母廷,該接口包含了init()、destroy()糊肤、doFilter()方法琴昆。init和destroy方法會被容器調(diào)用,doFilter方法用來在過濾器類里實現(xiàn)邏輯任務(wù)馆揉。

為了配置過濾器业舍,可以使用@WebFilter注解或在web.xml文件中使用<filter>和<filter-mapping>注冊。<filter>的定義必須在<filter-mapping>進(jìn)行設(shè)置升酣。

九舷暮、轉(zhuǎn)發(fā)和重定向

轉(zhuǎn)發(fā)請求時不重定向客戶端的URL,即瀏覽器地址欄的URL不會改變噩茄。ServletContext已經(jīng)內(nèi)置實現(xiàn)轉(zhuǎn)發(fā)的方法下面,調(diào)用getRequestDispatcher()方法獲取用來轉(zhuǎn)發(fā)請求的對象。調(diào)用該方法時绩聘,需要傳遞包含處理轉(zhuǎn)發(fā)請求的Servlet名稱的字符串沥割。獲取RequestDispatcher對象后耗啦,傳遞HttpServletRequest和HttpServletResponse對象給轉(zhuǎn)發(fā)方法forward()。

RequestDispatcher rd = servletContext.getRequestDispatcher("/NextServlet");
rd.forward(request, response);

當(dāng)特定URL被訪問時机杜,可以把瀏覽器的URL重定向到另外一個芹彬,即URL會改變。需要調(diào)用HttpServletResponse對象的sendRedirect()方法叉庐,傳遞重定向后的URL字符串舒帮。

httpServletResponse.sendRedirect("/anotherURL");

十、Cookie與Session

用戶打開瀏覽器陡叠,點擊多個超鏈接玩郊,訪問服務(wù)器多個Web資源,關(guān)閉瀏覽器枉阵,整個過程稱之為一個會話译红。保存會話數(shù)據(jù)有兩種方式:使用Cookie或Session。

1兴溜、Cookie

客戶端技術(shù)侦厚,程序把每個用戶的數(shù)據(jù)以cookie的形式寫給用戶各自的瀏覽器,當(dāng)訪問服務(wù)器中的Web資源時拙徽,會帶著用戶各自的數(shù)據(jù)刨沦。

Cookie可以看做是保存在客戶端的鍵值對數(shù)據(jù),當(dāng)使用瀏覽器打開應(yīng)用時膘怕,可以對這些數(shù)據(jù)進(jìn)行讀寫想诅。為了創(chuàng)建cookie,需要實例化一個javax.servlet.http.Cookie對象岛心,并為它分配鍵值来破,可以設(shè)置屬性來配置cookie。

Cookie cookie = new Cookie("sessionId","123456789");
cookie.setHttpOnly(true);
response.addCookie(cookie);

讀取服務(wù)端的cookie信息:

Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies){
    ......
}

2忘古、Session

服務(wù)器端技術(shù)徘禁,服務(wù)器為每個用戶的瀏覽器創(chuàng)建一個獨享的HttpSession對象,當(dāng)訪問服務(wù)器的Web資源時髓堪,把各自的數(shù)據(jù)放在各自的session中送朱。

通過請求獲取session對象:

HttpSession session = request.getSession(boolean create);

如果當(dāng)前請求不屬于任何會話,而且create參數(shù)為true旦袋,則創(chuàng)建一個會話骤菠,否則返回null。如果為false的時候疤孕,那就和不帶參數(shù)的getSession()等價了商乎。

獲取session對象之后,就可以直接使用它進(jìn)行各種操作了祭阀。

// 將value對象以name名稱綁定到會話
public void setAttribute(String name, Object value)
// 取得name的屬性值鹉戚,如果屬性不存在則返回null
public object getAttribute(String name)
// 從會話中刪除name屬性鲜戒,如果不存在不會執(zhí)行,也不會拋出錯誤
public void removeAttribute(String name)
// 返回和會話有關(guān)的枚舉值
public Enumeration getAttributeNames()
// 使會話失效抹凳,同時刪除屬性對象
public void invalidate()
// 用于檢測當(dāng)前用戶是否為新的會話
public Boolean isNew()
// 返回會話創(chuàng)建時間
public long getCreationTime()
// 返回在會話時間內(nèi)web容器接收到客戶最后發(fā)出的請求的時間
public long getLastAccessedTime()
// 返回在會話期間內(nèi)客戶請求的最長時間遏餐,單位是秒
public int getMaxInactiveInterval()
// 允許客戶客戶請求的最長時間
public void setMasInactiveInterval(int seconds)
// 返回當(dāng)前會話的上下文環(huán)境,ServletContext對象可以使Servlet與web容器進(jìn)行通信
ServletContext getServletContext()
// 返回會話期間的識別號
public String getId()

十一赢底、上傳和下載

1失都、上傳文件

首先要將enctype屬性的值設(shè)置成multipart/form-data,讓表單提交的數(shù)據(jù)以二進(jìn)制編碼的方式提交幸冻,在接收此請求的Servlet中用二進(jìn)制流來獲取內(nèi)容粹庞,就可以取得上傳文件的內(nèi)容,從而實現(xiàn)文件的上傳洽损。

2庞溜、下載文件

通過HttpServletResponse.setContentType方法設(shè)置響應(yīng)類型Content-Type頭字段的值,讓瀏覽器無法使用某種方式或激活某個程序來處理的MIME類型碑定。

response.setContentType("application/x-msdownload");

通過HttpServletResponse.setHeader方法設(shè)置響應(yīng)頭Content-Disposition的值流码。

response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");

調(diào)用HttpServletRespnse.getOutputStream方法返回的ServletOutputStream對象來向客戶端寫入附件文件的內(nèi)容。

InputStream inputStream = new FileInputStream(file);
ServletOutputStream ouputStream = response.getOutputStream();
byte b[] = new byte[1024];
while((n = inputStream.read(b)) != -1) {
    ouputStream.write(b, 0, n);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末延刘,一起剝皮案震驚了整個濱河市漫试,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌访娶,老刑警劉巖商虐,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異崖疤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)典勇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門劫哼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人割笙,你說我怎么就攤上這事权烧。” “怎么了伤溉?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵般码,是天一觀的道長。 經(jīng)常有香客問我乱顾,道長板祝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任走净,我火速辦了婚禮券时,結(jié)果婚禮上孤里,老公的妹妹穿的比我還像新娘。我一直安慰自己橘洞,他們只是感情好捌袜,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炸枣,像睡著了一般虏等。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上适肠,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天霍衫,我揣著相機(jī)與錄音,去河邊找鬼迂猴。 笑死慕淡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沸毁。 我是一名探鬼主播峰髓,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼息尺!你這毒婦竟也來了携兵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤搂誉,失蹤者是張志新(化名)和其女友劉穎徐紧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炭懊,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡并级,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了侮腹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘲碧。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖父阻,靈堂內(nèi)的尸體忽然破棺而出愈涩,到底是詐尸還是另有隱情,我是刑警寧澤加矛,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布履婉,位于F島的核電站,受9級特大地震影響斟览,放射性物質(zhì)發(fā)生泄漏毁腿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狸棍。 院中可真熱鬧身害,春花似錦、人聲如沸草戈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唐片。三九已至丙猬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間费韭,已是汗流浹背茧球。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留星持,地道東北人抢埋。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像督暂,于是被迫代替她去往敵國和親揪垄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法逻翁,類相關(guān)的語法饥努,內(nèi)部類的語法,繼承相關(guān)的語法八回,異常的語法酷愧,線程的語...
    子非魚_t_閱讀 31,623評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)缠诅,斷路器溶浴,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 0 系列目錄# WEB請求處理 WEB請求處理一:瀏覽器請求發(fā)起處理 WEB請求處理二:Nginx請求反向代理 本...
    七寸知架構(gòu)閱讀 13,954評論 22 190
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司管引,掛了不少戳葵,但最終還是拿到小米、百度汉匙、阿里、京東生蚁、新浪噩翠、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,240評論 11 349
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,810評論 0 11