web技術(shù)的發(fā)展
早期的web應(yīng)用主要是靜態(tài)頁面的瀏覽伪煤,這些靜態(tài)頁面使用HTML語言編寫敷搪,放在服務(wù)器上审丘,用戶使用瀏覽器通過HTTP協(xié)議請(qǐng)求服務(wù)器上的web頁面榕堰,服務(wù)器上的web服務(wù)器軟件接受到用戶發(fā)送的請(qǐng)求后足删,讀取請(qǐng)求URI所標(biāo)識(shí)的資源考赛,加上消息包頭發(fā)送給客戶端的瀏覽器巢株,瀏覽器解析響應(yīng)中的HTML數(shù)據(jù)廊驼,向用戶呈現(xiàn)多姿多彩的HTML頁面凿将。
但是隨著網(wǎng)絡(luò)的發(fā)展校套,很多線下業(yè)務(wù)開始向網(wǎng)上發(fā)展,基于Internet的web應(yīng)用也變得越來越復(fù)雜用戶所訪問的資源已不僅僅局限于服務(wù)器硬盤上存放的靜態(tài)網(wǎng)頁牧抵,更多的應(yīng)用需要根據(jù)用戶的請(qǐng)求動(dòng)態(tài)生成網(wǎng)頁信息笛匙,復(fù)雜的還需要從數(shù)據(jù)庫中提取信息,經(jīng)過一定的運(yùn)算犀变,生成一個(gè)頁面返回給客戶如何才能實(shí)現(xiàn)妹孙?
利用已經(jīng)實(shí)現(xiàn)HTTP協(xié)議的服務(wù)器端軟件,這些軟件預(yù)先給我們留出了擴(kuò)展的接口获枝,我們只需要按照一定的規(guī)則取提供相應(yīng)的擴(kuò)展功能蠢正,當(dāng)這類web服務(wù)器接受到客戶端請(qǐng)求后,判斷請(qǐng)求是否是訪問我們提供的擴(kuò)展功能省店,如果是嚣崭,將請(qǐng)求交由我們編寫的程序去處理笨触,處理完成后,程序?qū)⑻幚斫Y(jié)果交回web服務(wù)器軟件雹舀,web服務(wù)器軟件拿到結(jié)果后芦劣,再將結(jié)果作為相應(yīng)信息返回給客戶端。
早起使用的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ù)器接受到請(qǐng)求后唱蒸,發(fā)現(xiàn)這個(gè)請(qǐng)求是給CGI程序的邦鲫,于是就啟動(dòng)并運(yùn)行這個(gè)CGI程序,對(duì)用于請(qǐng)求進(jìn)行處理神汹。CGI程序解析請(qǐng)求中的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編寫困難,對(duì)用戶請(qǐng)求的響應(yīng)時(shí)間較長以進(jìn)程方式運(yùn)行導(dǎo)致性能受限制但狭。
-
1997年披诗,SUN公司推出了Servlet技術(shù),作為java陣營的CGI解決方案立磁,作為對(duì)微軟ASP(1996年推出)的推出呈队,SUN公司于1998年推出了JSP技術(shù),允許在HTML頁面中嵌入java腳本代碼唱歧,從而實(shí)現(xiàn)動(dòng)態(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容器所管理,用于生成動(dòng)態(tài)的內(nèi)容沿后,Servlet是平臺(tái)獨(dú)立的java類沿彭,編寫一個(gè)Servlet實(shí)際上就是按照Servlet規(guī)范編寫一個(gè)Java類,Servlet被編譯為平臺(tái)獨(dú)立的字節(jié)碼尖滚,可以被動(dòng)態(tài)地加載到支持java技術(shù)的web服務(wù)器中運(yùn)行喉刘。Servlet容器
Servlet容器也叫Servlet引擎瞧柔,是Web服務(wù)器或者應(yīng)用服務(wù)器的一部分,用戶在發(fā)送請(qǐng)求和響應(yīng)之上提供網(wǎng)絡(luò)服務(wù)睦裳,解碼基于MIME的請(qǐng)求造锅,格式化基于MIME的請(qǐng)求,Servlet不能獨(dú)立運(yùn)行推沸,必須被部署到Servlet容器中备绽,由容器實(shí)例化和調(diào)用Servlet的方法,Servlet容器在Servlet的生命周期內(nèi)包含和管理Servlet
-
對(duì)比CGI
- Servlet是單實(shí)例多線程的運(yùn)行方式鬓催,每個(gè)請(qǐng)求在一個(gè)獨(dú)立的線程中運(yùn)行肺素,提供服務(wù)的Servlet實(shí)例只有一個(gè)
- Servlet 具有可升級(jí)性,能響應(yīng)更多的請(qǐ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平臺(tái)豐富的類庫,使得各種應(yīng)用的開發(fā)更為容易
6.Servlet容器給Servlet提供額外的功能筝尾。
Tomcat
Tomcat是一個(gè)免費(fèi)的開源代碼的Servlet容器捡需,是Apache軟件基金會(huì)的一個(gè)頂級(jí)項(xiàng)目,由Apache,SUN和其他一些公司及個(gè)人共同開發(fā)而成筹淫,由于SUN的參與與支持站辉,最新的Servlet和JSP規(guī)范總是能在Tomcat中得到體現(xiàn)。Tomcat支持Servlet2.5Tomcat的安裝
安裝jdk,并且配置環(huán)境變量 path,CLASSPATH,JAVA_HOME
解壓tomcat即可
Tomcat的目錄結(jié)構(gòu)
bin 存放啟動(dòng)和關(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接口
init(ServletConfig config)
在Servlet實(shí)例化之后,Servlet容器會(huì)調(diào)用init()方法摧阅,來初始化該對(duì)象汰蓉,主要是為了讓servlet對(duì)象在處理客戶請(qǐng)求前完成一些初始化工作。例如建立數(shù)據(jù)庫的連接棒卷,獲取配置信息等顾孽。對(duì)于每個(gè)Servlet實(shí)例,init()方法只能被調(diào)用一次比规。Servlet容器通過config參數(shù)向Servlet傳遞配置信息岩齿。可以通過config獲取web應(yīng)用程序的初始化參數(shù)苞俘,還可以獲取ServletContext對(duì)象service(ServletRequest req,ServletResponse res)
容器調(diào)用service()方法處理客戶端的請(qǐng)求盹沈,在調(diào)用service()方法被容器調(diào)用之前,必須確保Init()方法正確完成,容器會(huì)構(gòu)造一個(gè)ServletRequest對(duì)象和ServletResponse對(duì)象作為參數(shù)傳遞給service()方法乞封。destroy();
當(dāng)容器檢測到一個(gè)Servlet對(duì)象應(yīng)該從服務(wù)中被移除的時(shí)候做裙,容器會(huì)調(diào)用該對(duì)象的destory方法,以便讓Servlet對(duì)象可以釋放它所使用的資源肃晚,保存數(shù)據(jù)到數(shù)據(jù)庫中锚贱。ServletConfig getServletConfig()
返回容器調(diào)用init()方法時(shí)傳遞給Servlet對(duì)象的ServletConfig對(duì)象String getServletInfo()
返回一個(gè)String類型的字符串,包含了關(guān)于Servlet的信息关串,例如版權(quán)拧廊,作者等。
ServletRequest
ServletRequest 對(duì)象晋修,用來封裝請(qǐng)求數(shù)據(jù)
- Object getAttribute(String name)
返回以name為名字的屬性的值吧碾,如果不存在,返回null - Enumeration getAttributeNames();
返回請(qǐng)求中所有可用的屬性的名字墓卦。返回一個(gè)枚舉集合 - void removeAttribute(String name);
移除請(qǐng)求中名字為name的屬性 - void setAttribute(String key,Object val);
在請(qǐng)求中保存一個(gè)鍵值對(duì)倦春。 - getCharacterEncoding()
返回請(qǐng)求正文使用的字符編碼的名字 - int getContentLength()
以字節(jié)為單位,返回請(qǐng)求正文的長度落剪。 - String getContentType()
返回正文的MIME類型 - ServletInputStream getInputStream()
- BufferedReader getReader()
- String getLocalAddr()
返回接收到請(qǐng)求的網(wǎng)絡(luò)接口的IP地址睁本。 - String getRemoteAddr()
返回發(fā)送請(qǐng)求的客戶端或最后一個(gè)代理服務(wù)器的IP地址 - String getRemoteHost()
返回發(fā)送請(qǐng)求的客戶端或者最后一個(gè)代理服務(wù)器的完整限定名 - String getLocalName()
返回接收到請(qǐng)求的IP接口的主機(jī)名 - int getLocalPort()
返回接收到請(qǐng)求的網(wǎng)絡(luò)接口的IP端口號(hào) - int getRemotePort()
返回發(fā)送請(qǐng)求的客戶端或最后一個(gè)代理服務(wù)器的IP源端口。 - String getParameter(String name)
返回請(qǐng)求中name參數(shù)的值忠怖,如果name參數(shù)有多個(gè)值呢堰,該方法返回值列表中的第一個(gè)值。如果請(qǐng)求中沒有找到該參數(shù)凡泣,返回null - Enumeration getParameterNames()
返回請(qǐng)求中包含的所有的參數(shù)的名字暮胧。 - String[] getParameterValues(String name);
返回請(qǐng)求中name參數(shù)所有的值 - String getProtocal()
返回請(qǐng)求使用的協(xié)議的名字和版本 例如: HTTP/1.1 - RequestDispatcher getRequestDispatcher(String path)
返回RequestDispather對(duì)象,作為path所定位的資源的封裝问麸。 - String getServerName()
返回請(qǐng)求發(fā)送到服務(wù)器的主機(jī)名 - int getServerPort()
返回請(qǐng)求發(fā)送到服務(wù)器的端口號(hào) - setCharacterEncoding(String env)
覆蓋在請(qǐng)求正文中所使用的字符編碼的名字。
ServletResponse對(duì)象钞翔,用來封裝響應(yīng)數(shù)據(jù)
- flushBuffer() 強(qiáng)制把任何在緩存中的內(nèi)容發(fā)送到客戶端
- int getBufferSize() 返回實(shí)際用于響應(yīng)的緩存的大小严卖,如果沒有使用緩存,這個(gè)方法返回0
- String getCharacterEncoding()
返回響應(yīng)中發(fā)送的正文所使用的字符編碼(MIME字符集) - String getContentType()
返回響應(yīng)中發(fā)送的正文所使用的MIME類型 - ServletOutputStream getOutputStream()
- PrintWriter getWriter()
- boolean isCommitted() 返回一個(gè)布爾值布轿,指示是否已經(jīng)提交了響應(yīng)哮笆。
- void reset() 清除在緩存中的任何數(shù)據(jù),包括狀態(tài)代碼和消息報(bào)頭汰扭。
- void resetBuffer() 清除在緩存中的響應(yīng)內(nèi)容稠肘,保留狀態(tài)代碼和消息包頭。
- void setBufferSize(int size)
設(shè)置響應(yīng)正文的緩存大小萝毛。 - void setCharacterEncoding(String charset)
設(shè)置發(fā)送到客戶端的響應(yīng)的字符編碼 - void setContentLength(int len)
設(shè)置內(nèi)容正文的長度 - void setContentType(String type)
設(shè)置要發(fā)送到客戶端的響應(yīng)的內(nèi)容類型项阴。例如:"text/html;charset=UTF-8"
ServletConfig
Servlet容器使用ServletConfig對(duì)象在Servlet初始化期間向它傳遞配置信息,一個(gè)ServletConfig對(duì)象笆包。
String getInitParameter(String name);
返回名字為name的初始化參數(shù)的值环揽,初始化參數(shù)在web.xml配置文件中進(jìn)行配置略荡。Enumeration getInitParameterNames()
返回Servlet所有初始化參數(shù)的名字的枚舉集合。ServletContext getServletContext()
返回Servlet上下文對(duì)象的引用歉胶。String getServletName()
返回Servlet實(shí)例的名字汛兜,這個(gè)名字是web應(yīng)用程序的部署描述符中指定。編寫一個(gè)Servlet實(shí)際上就是編寫一個(gè)實(shí)現(xiàn)了javax.servlet.Servlet接口的類通今。
GenericServlet
-
如果要編寫一個(gè)通用的Servlet粥谬,只需要從GenericServlet繼承,并且實(shí)現(xiàn)抽象方法service();
String getInitParameter(String name) Enumeration getInitParameterNames(); ServletContext getServletContext() init(ServletConfig config)
HttpServlet
-
在絕大多數(shù)的網(wǎng)絡(luò)應(yīng)用中辫塌,都是客戶端通過HTTP協(xié)議去訪問服務(wù)器端的資源我們編寫的Servlet也主要是應(yīng)用于HTTP協(xié)議的請(qǐng)求和響應(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) 針對(duì)HTTP1.1定義的7種請(qǐng)求方法GET,POST,HEAD,PUT,DELETE,TRACE,OPTION, HttpServlet提供了7個(gè)處理方法 doGet(HttpServletRequest req,HttpServletResponse resp) doPost(HttpServletRequest req,HttpServletResponse resp) ......
-
當(dāng)容器接受到一個(gè)針對(duì)HttpServlet對(duì)象的請(qǐng)求時(shí)一也,調(diào)用該對(duì)象中的方法順序如下:
- 調(diào)用公共的service()方法
- 在公共的service()方法中巢寡,首先將參數(shù)類型轉(zhuǎn)換為HttpServletRequest和HttpServletResponse,然后調(diào)用保護(hù)的service()方法椰苟,將轉(zhuǎn)換后的對(duì)象作為參數(shù)傳遞進(jìn)去
- 在保護(hù)的service方法中抑月,首先調(diào)用HttpServletRequest對(duì)象的getMethod方法,獲取HTTP請(qǐng)求方法的名稱舆蝴,然后根據(jù)請(qǐng)求方法的類型谦絮,調(diào)用相應(yīng)的doXxx()方法
HttpServletRequest
繼承自javax.servlet.servletRequest,在該接口中新增的方法如下:
- String getContextPath()
返回請(qǐng)求URI中表示請(qǐng)求上下文的部分,上下文路徑是請(qǐng)求URI的開始部分 - Cookie[] getCookies()
返回客戶端在此次請(qǐng)求中發(fā)送的所有的Cookie對(duì)象 - String getHeader(String name)
返回名字為name的請(qǐng)求報(bào)頭的值 - Enumeration getHeaderNames()
返回此次請(qǐng)求中包含的所有的報(bào)頭名字的枚舉集合 - Enumeration getHeaders(String name)
返回名字為name的請(qǐng)求報(bào)頭的所有值的枚舉集合 - String getMethod()
返回此次請(qǐng)求所使用的HTTP方法的名字 - String getServletPath()
返回請(qǐng)求URI中調(diào)用Servlet的部分 - HttpSession getSession()
返回和此次請(qǐng)求相關(guān)聯(lián)的Session - HttpSession getSession(boolean create)
返回此次請(qǐng)求相關(guān)聯(lián)的Session,如果沒有給客戶端分配Session,并且create參數(shù)為true,則創(chuàng)建一個(gè)新的Session,如果為false洁仗,此次請(qǐng)求沒有一個(gè)有效的HttpSession,返回null
HttpServletResponse
該接口繼承ServletResponse,新增的方法入下
- addCookie(Cookie cookie)
- addHeader(String name,String value);
- boolean containsHeader(String name)
- encodeRedirectURL(String url)
- 使用SessionID 對(duì)于重定向的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è)階段
- 加載和實(shí)例化
Servlet容器負(fù)責(zé)加載和實(shí)例化Servlet,當(dāng)Servlet容器啟動(dòng)時(shí)她奥,或者是在容器檢測到這個(gè)Servlet來響應(yīng)第一個(gè)請(qǐng)求時(shí)瓮增,創(chuàng)建Servlet實(shí)例。 - 初始化
在Servlet實(shí)例化之后哩俭,容器將調(diào)用Servlet的init()方法初始化這個(gè)對(duì)象绷跑。對(duì)于每個(gè)Servlet實(shí)例,init()方法只被調(diào)用一次, - 請(qǐng)求處理
Servlet容器調(diào)用Servlet的service()方法對(duì)請(qǐng)求進(jìn)行處理凡资。service執(zhí) 行之前init()方法必須成功執(zhí)行砸捏。 - 服務(wù)終止
當(dāng)容器檢測到一個(gè)Servlet實(shí)例應(yīng)該從服務(wù)中被移除的時(shí)候,容器就會(huì)調(diào)用實(shí)例的destory()方法。釋放資源带膜。
跳轉(zhuǎn)
RequestDispatcher接口
該對(duì)象由Servlet容器創(chuàng)建吩谦,用于封裝一個(gè)由路徑標(biāo)識(shí)的服務(wù)器資源。利用該對(duì)象可以將請(qǐng)求轉(zhuǎn)發(fā)給其他的Servlet或jsp頁面膝藕。
forword(ServletRequest req,ServletResponse resp)
該方法用于將請(qǐng)求從一個(gè)Servlet傳遞給服務(wù)器上的另外的Servlet式廷,jsp或者h(yuǎn)tml文件,在forword方法調(diào)用之后芭挽,之前在響應(yīng)緩存中沒有提交的內(nèi)容將會(huì)被自動(dòng)清除滑废。該方法將請(qǐng)求轉(zhuǎn)發(fā)給其他Servlet,將又被調(diào)用的Servlet負(fù)責(zé)對(duì)請(qǐng)求做出響應(yīng)袜爪,原先Servlet執(zhí)行終止蠕趁。include(ServletRequest req,ServletResponse resp)
該方法用于將請(qǐng)求轉(zhuǎn)發(fā)給其他Servlet,被調(diào)用的Servlet對(duì)該請(qǐng)求做出的響應(yīng)將并入原來的響應(yīng)對(duì)象中辛馆,原先的Servlet還可以繼續(xù)輸出響應(yīng)信息俺陋。forword(),include()屬于內(nèi)部請(qǐng)求,瀏覽器地址不發(fā)生改變昙篙,客戶端僅向服務(wù)器端發(fā)送一次請(qǐng)求
sendRedirect()
該方法由HttpServletResponse對(duì)象提供腊状,
表示重定向到另外一個(gè)請(qǐng)求中。屬于外部請(qǐng)求苔可。重定向相當(dāng)于重新向服務(wù)器發(fā)送請(qǐng)求缴挖,瀏覽器地址發(fā)送改變