Tomcat設(shè)置熱配置:修改文件后不用重啟Tomcat服務(wù)器收擦。
Tomcat設(shè)置虛擬路徑
Servlet:Servlet就是一個(gè)接口,定義了Java類被瀏覽器訪問(wèn)到(tomcat識(shí)別)的規(guī)則囊卜。
具體內(nèi)容由我們自己實(shí)現(xiàn),在瀏覽器可以調(diào)用Servlet的實(shí)現(xiàn)類的方法眠菇。
配置Servlet
1边败、 在web.xml中配置:
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>cn.itcast.web.servlet.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
2、使用注解配置:
Servlet 3.0之后支持使用的方式就可以配置了捎废,注解寫在Servlet的實(shí)現(xiàn)類中笑窜,資源路徑就是url-pattern中的內(nèi)容。
WebServlet注解內(nèi)容:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";//相當(dāng)于<Servlet-name>
String[] value() default {};//代表urlPatterns()屬性配置,默認(rèn)就是這個(gè)
String[] urlPatterns() default {};//相當(dāng)于<url-pattern>
int loadOnStartup() default -1;//相當(dāng)于<load-on-startup>
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
三登疗、Servlet的生命周期
1. 被創(chuàng)建:執(zhí)行init方法排截,只執(zhí)行一次
* Servlet什么時(shí)候被創(chuàng)建?
* 默認(rèn)情況下辐益,第一次被訪問(wèn)時(shí)断傲,Servlet被創(chuàng)建
* 可以配置執(zhí)行Servlet的創(chuàng)建時(shí)機(jī)。
* 在<servlet>標(biāo)簽下配置
1. 第一次被訪問(wèn)時(shí)智政,創(chuàng)建
<load-on-startup>的值為負(fù)數(shù)
2. 在服務(wù)器啟動(dòng)時(shí)认罩,創(chuàng)建
<load-on-startup>的值為0或正整數(shù)
Servlet的init方法,只執(zhí)行一次续捂,說(shuō)明一個(gè)Servlet在內(nèi)存中只存在一個(gè)對(duì)象垦垂,Servlet是單例的
多個(gè)用戶同時(shí)訪問(wèn)時(shí)宦搬,可能存在線程安全問(wèn)題。
解決:盡量不要在Servlet中定義成員變量劫拗。即使定義了成員變量间校,也不要對(duì)修改值
- 提供服務(wù):執(zhí)行service方法,執(zhí)行多次
- 每次訪問(wèn)Servlet時(shí)页慷,Service方法都會(huì)被調(diào)用一次憔足。
- 被銷毀:執(zhí)行destroy方法,只執(zhí)行一次
- Servlet被銷毀時(shí)執(zhí)行酒繁。服務(wù)器關(guān)閉時(shí)滓彰,Servlet被銷毀
- 只有服務(wù)器正常關(guān)閉時(shí),才會(huì)執(zhí)行destroy方法欲逃。
- destroy方法在Servlet被銷毀之前執(zhí)行找蜜,一般用于釋放資源
四、Servlet的執(zhí)行原理
Servlet不需要主方法就能執(zhí)行稳析,因?yàn)橛玫搅朔瓷涞募夹g(shù)。
五弓叛、Servlet的繼承結(jié)構(gòu):
Servlet -- 接口:
實(shí)現(xiàn)Servlet接口的實(shí)現(xiàn)類彰居,五個(gè)抽象方法都得實(shí)現(xiàn)。
|
GenericServlet -- 抽象類:
空實(shí)現(xiàn)了其余四個(gè)抽象方法撰筷,繼承該抽象類只需要實(shí)現(xiàn)service()即可陈惰。
|
HttpServlet -- 抽象類:
對(duì)HTTP協(xié)議進(jìn)行了封裝、空實(shí)現(xiàn)了五個(gè)方法毕籽、只需要重寫doGet/doPost方法即可抬闯、根據(jù)請(qǐng)求的方式來(lái)執(zhí)行不同的代碼。
六关筒、HTML協(xié)議
1.HTML協(xié)議是基于TCP/IP協(xié)議的一種高級(jí)協(xié)議
2.默認(rèn)端口號(hào)是:80
3.基于請(qǐng)求溶握、響應(yīng)模型:一次請(qǐng)求對(duì)應(yīng)一次響應(yīng)
4. 無(wú)狀態(tài)的:每次請(qǐng)求之間相互獨(dú)立,不能交互數(shù)據(jù)
HTML協(xié)議1.0版本蒸播,每次請(qǐng)求響應(yīng)都會(huì)建立一個(gè)新的連接睡榆,顯然這樣是影響性能的。
HTML協(xié)議1.1版本袍榆、復(fù)用連接
請(qǐng)求消息的格式
請(qǐng)求行
請(qǐng)求方式 請(qǐng)求url 請(qǐng)求協(xié)議/版本
GET /login.html HTTP/1.1
請(qǐng)求頭
客戶端通過(guò)請(qǐng)求頭的鍵值對(duì)胀屿,告訴服務(wù)器一些信息。
常見(jiàn)的請(qǐng)求頭的內(nèi)容:
- User-Agent:告訴服務(wù)器一些瀏覽器的版本等信息包雀。
在服務(wù)器端獲取User-Agent宿崭,可以解決兼容性的問(wèn)題。 - Referer:告訴服務(wù)器才写,這個(gè)連接是從哪里來(lái)的葡兑。
1.防止別的網(wǎng)站(盜版網(wǎng)站)盜取鏈接使用奴愉。
2.可以進(jìn)行統(tǒng)計(jì)流量的來(lái)源。
請(qǐng)求空行
用來(lái)分隔請(qǐng)求體與請(qǐng)求頭的铁孵,注意:只有POST請(qǐng)求方式有請(qǐng)求體锭硼。
請(qǐng)求體
封裝POST請(qǐng)求消息的請(qǐng)求參數(shù)的
關(guān)于GET方式與POST方式
1、請(qǐng)求方式:
直接訪問(wèn)網(wǎng)頁(yè)資源是GET方式蜕劝,表單中設(shè)置POST方式檀头,再提交后才是POST方式。
GET方式與POST方式的區(qū)別:
GET
1岖沛、get是相當(dāng)于是明文傳輸暑始,且url長(zhǎng)度有限制,根據(jù)瀏覽器不同限制的長(zhǎng)度不同婴削。
2廊镜、填入表單的請(qǐng)求參數(shù)會(huì)顯示到地址欄后面、不太安全唉俗。
3嗤朴、沒(méi)有請(qǐng)求體。POST
1虫溜、post的請(qǐng)求參數(shù)在請(qǐng)求體中雹姊,不是明文傳輸
2.、請(qǐng)求的url長(zhǎng)度沒(méi)有限制的
3.衡楞、相對(duì)安全
七吱雏、Request對(duì)象與Response對(duì)象
request對(duì)象和response對(duì)象的原理
- request和response對(duì)象是Tomcat服務(wù)器給我們創(chuàng)建的。
- request對(duì)象是來(lái)獲取請(qǐng)求消息瘾境,response對(duì)象是來(lái)設(shè)置響應(yīng)消息做出回應(yīng)的歧杏。
1、Request對(duì)象(請(qǐng)求)
Request對(duì)象的繼承結(jié)構(gòu):
ServletRequest -- 接口
| 繼承
HttpServletRequest -- 接口
| 實(shí)現(xiàn)
org.apache.catalina.connector.RequestFacade 類(tomcat)
獲取請(qǐng)求行的數(shù)據(jù)的方法
請(qǐng)求行中的數(shù)據(jù)有:請(qǐng)求方式迷守、請(qǐng)求的URL犬绒、HTTP協(xié)議版本信息
- 1、獲取請(qǐng)求方式:
String getMethod() - 2盒犹、獲取URL中的虛擬路徑的方法:
String getContextPath() - 3懂更、獲取Servlet資源路徑: (常用)
String getServletPath() - 4、獲取get方式的請(qǐng)求參數(shù):
String getQueryString() - 5急膀、獲取URI路徑
String getRequestURI(): (常用) - 6沮协、獲取URL路徑
StringBuffer getRequestURL()
- 7、獲取HTTP協(xié)議版本:
String getProtocol() - 8卓嫂、獲取客戶機(jī)的IP地址:
String getRemoteAddr()
獲取請(qǐng)求頭中的數(shù)據(jù)
- 1慷暂、(常用)String getHeader(String name):通過(guò)請(qǐng)求頭的名稱獲取請(qǐng)求頭的值
- 2、Enumeration<String> getHeaderNames():獲取所有的請(qǐng)求頭名稱
獲取請(qǐng)求頭的數(shù)據(jù)(使用流)
步驟:
- 1行瑞、BufferedReader getReader():獲取字符輸入流奸腺,只能操作字符數(shù)據(jù) 。
- 2血久、ServletInputStream getInputStream():獲取字節(jié)輸入流突照,可以操作所有類型數(shù)據(jù)
- 3、使用流對(duì)象氧吐,獲取數(shù)據(jù)讹蘑。
POST方法和GET方法都可以使用的、獲取請(qǐng)求參數(shù)的方法(常用)
- String getParameter(String name):根據(jù)參數(shù)名稱獲取參數(shù)值
- String[] getParameterValues(String name):根據(jù)參數(shù)名稱獲取參數(shù)值的數(shù)組
- Enumeration<String> getParameterNames():獲取所有請(qǐng)求的參數(shù)名稱
- Map<String,String[]> getParameterMap():獲取所有參數(shù)的map集合
關(guān)于請(qǐng)求參數(shù)亂碼問(wèn)題:
Q:為什么會(huì)出現(xiàn)亂碼筑舅?
A:request對(duì)象是Tomcat創(chuàng)建的座慰,所以解析請(qǐng)求參數(shù)使用的是Tomcat的編碼集iso-8859-1,但是瀏覽器使用的是html設(shè)置的編碼集(utf-8)翠拣,所以就亂碼了版仔。
目前Tomcat 8 已經(jīng)解決了get方法的亂碼問(wèn)題,但是post方法依然還會(huì)亂碼误墓。
需要我們自己設(shè)置編碼集蛮粮。
request.setCharacterEncoding("utf-8");
2.Response對(duì)象(響應(yīng))
響應(yīng)消息與請(qǐng)求消息的格式類似:
-
響應(yīng)行
內(nèi)容:協(xié)議/版本 響應(yīng)狀態(tài)碼 狀態(tài)碼描述- 狀態(tài)碼分類:
- 1xx:服務(wù)器就收客戶端消息蝉揍,但沒(méi)有接受完成,等待一段時(shí)間后畦娄,發(fā)送1xx多狀態(tài)碼
- 2xx:成功。代表:200
- 3xx:重定向弊仪。代表:302(重定向)熙卡,304(訪問(wèn)緩存)
- 4xx:客戶端錯(cuò)誤。 代表: 404(請(qǐng)求路徑?jīng)]有對(duì)應(yīng)的資源)励饵、405:請(qǐng)求方式?jīng)]有對(duì)應(yīng)的doXxx方法 (例如post方式的請(qǐng)求驳癌,卻沒(méi)有doPost方法。)
- 5xx:服務(wù)器端錯(cuò)誤役听。代表:500(服務(wù)器內(nèi)部出現(xiàn)異常)
- 狀態(tài)碼分類:
- 響應(yīng)頭
- 常見(jiàn)響應(yīng)頭:
- Content-Type:服務(wù)器告訴客戶端本次響應(yīng)體數(shù)據(jù)格式以及編碼格式颓鲜。
- Content-disposition:服務(wù)器告訴客戶端以什么格式打開響應(yīng)體數(shù)據(jù)。
- in-line:默認(rèn)值,在當(dāng)前頁(yè)面內(nèi)打開
- attachment;filename=xxx:以附件形式打開響應(yīng)體典予。文件下載
- 常見(jiàn)響應(yīng)頭:
- 響應(yīng)空行
用于分隔響應(yīng)頭與響應(yīng)體的甜滨。 - 響應(yīng)體
用于傳輸數(shù)據(jù)
Response對(duì)象是用來(lái)設(shè)置響應(yīng)消息的。
①瘤袖、設(shè)置響應(yīng)行
- 設(shè)置狀態(tài)碼:setStatus(int sc)
②衣摩、設(shè)置響應(yīng)頭 - setHeader(String name, String value)
③、設(shè)置響應(yīng)體 - 獲取Tomcat提供的輸出流對(duì)象捂敌,向響應(yīng)體中寫數(shù)據(jù)艾扮,輸出到瀏覽器既琴。
- PrintWriter getWriter()、獲得字符輸出流(打印流)
- ServletOutputStream getOutputStream()泡嘴、獲得字節(jié)輸出流
關(guān)于輸出亂碼問(wèn)題:
Q:為什么會(huì)亂碼甫恩?
A:因?yàn)檩敵隽鲗?duì)象是Tomcat給的,編碼集是Tomcat設(shè)置的ISO-8859-1酌予,瀏覽器解析請(qǐng)求體是用的系統(tǒng)的編碼集(GBK)磺箕,所以對(duì)應(yīng)不上就亂碼了。
解決方法:
- 1.設(shè)置流的編碼集:
response.setCharacterEncoding("utf-8"); - 設(shè)置瀏覽器解析的編碼集:
response.setHeader("content-type","text/html;charset=utf-8");
- 設(shè)置瀏覽器解析的編碼集:
兩步合一的簡(jiǎn)便方法:
- response.setContentType("text/html;charset=utf-8");
重定向:
步驟:
- 1.設(shè)置狀態(tài)碼為302、
response.setStatus(302); - 2.設(shè)置重定向地址莱褒、由響應(yīng)頭中的location頭指定:
response.setHeader("location","重定向的地址");
一步設(shè)置重定向:
- response.sendRedirect("重定向的地址");
重定向(redirect)與請(qǐng)求轉(zhuǎn)發(fā)(forward)的區(qū)別:
-
重定向
- 地址欄會(huì)發(fā)生改變
- 可以重定向到服務(wù)器外的資源
- 重定向是兩次請(qǐng)求击困、重定向不能由request域共享數(shù)據(jù)。
-
請(qǐng)求轉(zhuǎn)發(fā)
- 地址欄不會(huì)改變
- 只能轉(zhuǎn)發(fā)到當(dāng)前服務(wù)器中的資源
-
轉(zhuǎn)發(fā)是一次請(qǐng)求广凸、轉(zhuǎn)發(fā)可以由request域共享數(shù)據(jù)阅茶。
八、請(qǐng)求轉(zhuǎn)發(fā):服務(wù)器內(nèi)部的資源訪問(wèn)
步驟:
- 通過(guò)request對(duì)象獲取請(qǐng)求轉(zhuǎn)發(fā)器對(duì)象:
RequestDispatcher getRequestDispatcher(String path) - 使用RequestDispatcher對(duì)象來(lái)進(jìn)行轉(zhuǎn)發(fā):
forward(ServletRequest request, ServletResponse response)
特點(diǎn):
- 瀏覽器地址欄路徑不發(fā)生變化
- 只能轉(zhuǎn)發(fā)到當(dāng)前服務(wù)器內(nèi)部資源中谅海。
- 轉(zhuǎn)發(fā)是一次請(qǐng)求
九脸哀、路徑的虛擬目錄的使用情況
規(guī)則:判斷定義的路徑是給誰(shuí)用的?判斷請(qǐng)求將來(lái)從哪兒發(fā)出
-
1扭吁、給客戶端瀏覽器請(qǐng)求資源使用:需要加虛擬目錄(項(xiàng)目的訪問(wèn)路徑)
- 建議虛擬目錄動(dòng)態(tài)獲茸卜洹:request.getContextPath()
- 重定向:因?yàn)槭强蛻舳苏?qǐng)求的。
-
2侥袜、 給服務(wù)器請(qǐng)求資源使用:不需要加虛擬目錄
- 轉(zhuǎn)發(fā)路徑:因?yàn)槭欠?wù)器請(qǐng)求的蝌诡。
十、共享數(shù)據(jù)——域?qū)ο?/h1>
域?qū)ο螅阂粋€(gè)有作用范圍的對(duì)象枫吧,可以在范圍內(nèi)共享數(shù)據(jù)
request域:一次請(qǐng)求的范圍浦旱,一般用于請(qǐng)求轉(zhuǎn)發(fā)的多個(gè)資源中共享數(shù)據(jù)
1、向域?qū)ο笾写鎯?chǔ)數(shù)據(jù):
void setAttribute(String name,Object obj)
2九杂、通過(guò)鍵獲取值:
Object getAttitude(String name)
3颁湖、通過(guò)鍵移除鍵值對(duì)
void removeAttribute(String name):
十一、ServletContext:代表整個(gè)web應(yīng)用
如何獲壤 甥捺?
- 通過(guò)request對(duì)象獲取:request.getServletContext();
- 通過(guò)HttpServelet獲壬亚妗:this.getServletContext();
作用:- 1.獲取MIME類型
- 什么是MIME類型涎永?一種互聯(lián)網(wǎng)通信過(guò)程中定義的文件數(shù)據(jù)類型。
格式為: 大類型/小類型
例如:text/html、image/jpeg
context.getMimeType(String file)
- 什么是MIME類型涎永?一種互聯(lián)網(wǎng)通信過(guò)程中定義的文件數(shù)據(jù)類型。
- 2.作為域?qū)ο?/strong>
因?yàn)镾ervletContext對(duì)象是整個(gè)web應(yīng)用谷饿,所以所有的servlet資源都能訪問(wèn)到存在ServletContext對(duì)象中的數(shù)據(jù),比較的不安全妈倔。
相比request域?qū)ο蟮姆秶且淮握?qǐng)求經(jīng)過(guò)的servlet博投、ServletContext的范圍太大了。
ServletContext對(duì)象的生命周期很長(zhǎng)盯蝴,從服務(wù)器啟動(dòng)到服務(wù)器關(guān)閉毅哗。
- 1.獲取MIME類型
- 3.獲取文件的真實(shí)(服務(wù)器)路徑
在之前獲取的文件都是默認(rèn)在src路徑下的,使用ClassLoader就能獲取捧挺。
但是ClassLoader并獲取不了web路徑下的文件虑绵。
這時(shí)就需要ServletContext對(duì)象來(lái)獲取了。
String b = context.getRealPath("/a.txt");//web目錄下資源訪問(wèn)
D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded\a.txt
String c = context.getRealPath("/WEB-INF/b.txt");//WEB-INF目錄下的資源訪問(wèn)
D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded\WEB-INF\b.txt
String a = context.getRealPath("/WEB-INF/classes/c.txt");//src目錄下的資源訪問(wèn)
D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded\WEB-INF\classes\c.txt
服務(wù)器路徑是:D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded
(本地)工作空間路徑是:D:\ideaProject\basic-code\Servlet-Response