1.Servlet 學(xué)習(xí)大綱
- servlet 概念以及相關(guān)接口簡介
- servlet 執(zhí)行過程
- servlet 路徑映射
- 缺省servlet --應(yīng)用
- servlet生命周期
- servlet自動加載
- servlet線程安全
8)servletConfig 對象
9)servlet相關(guān)接口詳情 - servletContext對象 --知識點
Servlet就是Controller, 需要在web.xml
中配置它。
2.手動導(dǎo)入Jar包:
相對于maven而言倘潜。
參考:
https://www.oschina.net/question/2005688_166884
先把下載的jar包復(fù)制到WEB-INF/lib下绷柒,然后需要:打開 File -> Project Structure -> Modules -> Dependencies ->綠色 加號 -> 1. Jars + dep....
3.如何去開發(fā)一個servlet?
步驟:
1)編寫一個java類涮因,繼承于HttpServlet類
2)重寫doGet和doPost方法
3)servlet程序交給tomcat服務(wù)器運行废睦!
3-1:servlet程序的class 碼拷貝到WEB-INF/classes目錄中
3-2:在web.xml文件中進行配置
4.web.xml
中配置servlet:
Servlet中的映射路徑:
url-pattern | 瀏覽器輸入
精確匹配:
/first | http://localhost:8080/first
/ypd/first | http://localhost:8080/ypd/first
模糊匹配:
/* | http://localhost:8080/任意路徑
*.后綴名 |
*.do |
*.action |
*.html (偽靜態(tài)) |
注意:不能同時使用2種模糊匹配。
當有輸入的url有讀個servlet同事被匹配的情況下:
精確匹配優(yōu)先(長的最像有限被匹配)
以后綴名(eg:*.do, *.html)結(jié)尾的模糊匹配優(yōu)先級最低蕊退!
注意: /*
等同于 /
郊楣。 servlet缺省路徑,是tomcat內(nèi)置的一個路徑瓤荔。該路徑相對應(yīng)的是一個DefaultServlet(缺省servlet)净蚤。這個缺省的servlet的作用是用于解析web應(yīng)用的靜態(tài)資源文件。
web.xml
配置的映射路徑優(yōu)先級要高些输硝。
url中輸入http://localhost:8080/index.html 如何訪問文件今瀑??
- 首先到當前目錄下的web.xml文件查找是否有匹配的url-pattern。如果匹配到橘荠,就調(diào)用屿附。
2)如果沒有匹配到,則交給tomcat的內(nèi)置的DefaultServlet去處理哥童。
3)DefaultServlet 程序到應(yīng)用的根目錄下查找是否存在一個名為index.html的靜態(tài)文件挺份。如果找到該文件,則讀取改文件內(nèi)容贮懈,返回給瀏覽器匀泊。
eg:
<!-- 配置一個servlet -->
<servlet>
<!-- servlet 的內(nèi)部名稱,自定義朵你。精良有意義 -->
<servlet-name>FirstServlet</servlet-name>
<!-- servlet的類全名:包名+簡單類名 -->
<servlet-class>com.ypd.web5.FirstServlet</servlet-class>
</servlet>
<!-- servlet的映射配置 -->
<servlet-mapping>
<!-- servlet的內(nèi)部名稱各聘,一定要和上面的內(nèi)部名稱保持一致! -->
<servlet-name>FirstServlet</servlet-name>
<!-- servlet的映射路徑(訪問servlet的名稱) -->
<url-pattern>/first</url-pattern>
</servlet-mapping>
要注意:Servlet的class一定要是public class的抡医,否則不能訪問躲因。
前提:tomcat 服務(wù)器啟動時,首先加載webapps中的每個web應(yīng)用的配置文件 web.xml
servlet向瀏覽器輸出信息:
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
// 向瀏覽器輸出內(nèi)容
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("this is my servlet");
}
}
注意:如果不寫response.setContentType("text/html;charset=UTF-8");
這一句忌傻,有的時候回報405
錯大脉。
5.servlet實現(xiàn)
通過反射:
a) 構(gòu)造Servlet對象
b) 然后調(diào)用servlet中的方法
6.一個項目中要么是動態(tài)文件要么是靜態(tài)文件。
靜態(tài)文件:index.html
動態(tài)文件:servlet
先找動態(tài)的芯勘,再找靜態(tài)文件箱靴。
7.servlet的生命周期(重點):
servlet的生命周期就是servlet類對象什么時候創(chuàng)建腺逛,調(diào)用什么方法荷愕,什么時候銷毀,銷毀的時候又做了什么事情棍矛。
servlet程序的生命周期是由tomcat服務(wù)器控制的安疗。
servlet 方法
1)構(gòu)造方法:
public LifeDemo() {
2)init方法
public void init(ServletConfig config) throws ServletException {
3)service 方法
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
4)destory 方法
public void destroy() {
構(gòu)造方法:創(chuàng)建servlet對象的時候調(diào)用。第一次訪問ervlet的時候創(chuàng)建够委。
init
方法:創(chuàng)建完servlet對象的時候荐类。
service
方法:每次發(fā)出請求時候調(diào)用。
destory
方法:銷毀servlet對象時候調(diào)用茁帽。停止服務(wù)器或者重新部署web應(yīng)用的時候玉罐。
4個方法全部都是由服務(wù)器決定的。
8.servlet的自動加載
默認情況下潘拨,第一次訪問servlet時候創(chuàng)建servlet對象吊输。如果servlet的構(gòu)造方法或者init方法中執(zhí)行了比較多的邏輯代碼,那么導(dǎo)致用戶第一次訪問servlet的時候比較慢铁追。
改變servlet創(chuàng)建對象的時機:提前加載web應(yīng)用的時候季蚂。
在servlet的配置信息(web.xml
)中徐伐,加上一個<load-on-startup>
即可首启。就會在tomcat服務(wù)器啟動的時候自動加載。
注意,其中的<load-on-startup>1</load-on-startup>吗坚,這個1
,數(shù)值越大,優(yōu)先級越低徘跪。
servlet是單例讳推。
servlet在tomcat中的運行機制是:單實例多線程。
如果多個線程同事訪問了servlet對象的共享數(shù)據(jù)(成員變量)可能會引發(fā)線程安全問題葵腹。
synchronized (ThreadDemo.class) { // 鎖對象必須是唯一的罪治。ThreadDemo.class 也就是這個servlet的類對象,是唯一的礁蔗。
}
因為servlet是多線程的觉义,所以當多個servlet的線程同事訪問了servlet的共享數(shù)據(jù),如成員變量浴井,可能會引發(fā)線程安全問題晒骇。
解決方法:
1)把使用到共享數(shù)據(jù)的代碼塊進行同步(synchronized)
2)建議在servlet類中盡量不要使用成員變量。因為synchronized
會等待磺浙,盡量少用洪囤。哪里使用到了成員變量,那里就同步撕氧,以避免因為同步而導(dǎo)致并發(fā)效率降低瘤缩。
Servlet 學(xué)習(xí):
HttpServletRequest 請求對象: 獲取請求信息
HttpServletResponse 響應(yīng)對象: 設(shè)置響應(yīng)對象
ServletConfig對象: servlet配置對象
ServletContext對象: servlet的上下文對象
9.ServletConfig對象:
作用:主要用于加載servlet的初始化參數(shù)。
創(chuàng)建和得到:
創(chuàng)建的時機:在創(chuàng)建servlet對象之后伦泥,在調(diào)用init方法之前創(chuàng)建剥啤。
得到ServletConfig:直接從有參數(shù)的init方法中得到。
servlet的初始化參數(shù)配置:
ServletConfig的API不脯。
ServletConfig是對應(yīng)的:
<servlet>
<servlet-name>ConfigDemo</servlet-name>
<servlet-class>com.ypd.config.ConfigDemo</servlet-class>
<init-param>
<param-name>path</param-name>
<param-value>/Users/leo/Downloads/圖片1.png</param-value>
</init-param>
</servlet>
其中的<init-param>
的信息府怯。
String path = config.getInitParameter("path"); // 這里獲取path
File file = new File(path);
因為有封裝,我們可以直接拿來用防楷。
this.getServletConfig() // 就獲得了config對象
10.ServletContext對象
ServletContext:servlet上下文對象牺丙,表示一個當前的web應(yīng)用環(huán)境。一個web應(yīng)用中复局,只有一個ServletContext冲簿。ServletConfig可以有多個。
ServletContext創(chuàng)建和獲纫诨琛:
創(chuàng)建:在加載web應(yīng)用時候峦剔,創(chuàng)建對象。
得到:從ServletConfig的getServletContext方法得到龙优。
Sun公司設(shè)計:
1)先創(chuàng)建ServletConfig對象: ServletContext context = new ServletContext;
2)再創(chuàng)建ServletConfig對象: ServletConfig config = new ServletConfig(); config.setServletContext(context);
class ServletConfig {
ServletContext context;
public ServletContext getServletContext() {
return context;
}
}
所以羊异,ServletContext是從ServletConfig中取得的事秀。
注意;
有了 this.getServletConfig()
, 下面就可以不寫了野舶。
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.config = config;
}
11.ServletContext的作用:
ServletContext對象的核心API(作用):
- getContextPath()
得到web應(yīng)用路徑: 也就是部署到tomcat服務(wù)器上面的web應(yīng)用名稱
ServletContext context = this.getServletConfig().getServletContext(); // 也可以this.getServletContext(); 后者推薦易迹。點擊查看源碼的話,也就是前者平道。
注意:修改了web.xml
的文件后睹欲,運行ItelliJ IDEA 的debugger后, 需要選擇Restart Server一屋。如果只是修改了jsp,servlet等java代碼窘疮,可以不選擇Restart Server,只選擇Update classes and resources.
應(yīng)用到請求重定向:
String contextPath = this.getServletContext().getContextPath();
response.sendRedirect(contextPath + "/index.html");
12.配置web應(yīng)用參數(shù)冀墨,也叫上下文參數(shù)闸衫。
注意:IntelliJ IDEA 的輸出 System.out.prsintln()
快捷鍵是:sout
注意:兩種配置參數(shù)的區(qū)別
<context-param>
<param-name>ContextA</param-name>
<param-value>ContextA's value</param-value>
</context-param>
和
<servlet>
<servlet-name>ConfigDemo</servlet-name>
<servlet-class>com.ypd.config.ConfigDemo</servlet-class>
<init-param>
<param-name>path</param-name>
<param-value>/Users/luowensheng/Downloads/圖片1.png</param-value>
</init-param>
<init-param>
<param-name>aaa</param-name>
<param-value>aaa's value</param-value>
</init-param>
</servlet>
前者是全局的,后者是局部的诽嘉。
13.域?qū)ο螅ㄖ攸c):
域?qū)ο螅鹤饔糜糜诒4鏀?shù)據(jù)和獲取數(shù)據(jù)蔚出。可以在不同的動態(tài)資源中共享數(shù)據(jù)虫腋。
域?qū)ο缶褪且粋€對象骄酗。域?qū)ο缶褪谴鏀?shù)據(jù)的容器。
案例:(將Servlet1的name=eric共享給Servlet2)
Servlet1 Servlet2
name=eric
方案1:(傳參)
response.sendRedirect("/Servlet2?name=eric") request.getParameter("name") 獲取
局限:自能傳遞字符串類型悦冀。
如果想要傳遞對象就不可以了趋翻。
方案2:(域?qū)ο螅?/p>
可以共享任意類型數(shù)據(jù)。
ServletContext
就是一個域?qū)ο蠛畜。梢酝瓿蓴?shù)據(jù)共享踏烙。
共享數(shù)據(jù),有2個動作茁影,一個是保存宙帝,另外一個是獲取丧凤。還可以刪除數(shù)據(jù)募闲。
Servlet1中,保存數(shù)據(jù):
// 1.得到域?qū)ο?ServletContext也是域?qū)ο?ServletContext context = this.getServletContext();
// 2.把數(shù)據(jù)保存到域?qū)ο笾?context.setAttribute("context_demo3_name", "eric"); // 注意也可以保存對象愿待。
Servlet2中浩螺,取出數(shù)據(jù):
ServletContext context = this.getServletContext();
String context_demo3_name = (String)context.getAttribute("context_demo3_name");
可以使用removeAttribute(名稱)
移除。
ServletContext域?qū)ο螅鹤饔梅秶谡麄€web應(yīng)用中都有效仍侥。
所有域?qū)ο螅?/p>
HttpServletRequest域?qū)ο? ServletContext域?qū)ο? HttpSession域?qū)ο? PageContext域?qū)ο?
RequestDispatcher.forward()方法將當前的request和response重定向到該 RequestDispacher指定的資源要出。// 也就是重定向頁面,傳遞request和response參數(shù)农渊。
例子:
1)轉(zhuǎn)發(fā)
// 轉(zhuǎn)發(fā)患蹂。實現(xiàn)的效果和重定向是一樣的。
RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/index.html");
rd.forward(req, resp);
還有一種重定向方法:
2)重定向
String path = this.getServletContext().getContextPath(); // 這句就是獲取當前應(yīng)用的根目錄
resp.sendRedirect(path + "/index.html");
兩者區(qū)別:
1)前者的瀏覽器地址欄保留之前的,后者的瀏覽器地址欄會變化為新的传于。(轉(zhuǎn)發(fā)地址欄不會改變囱挑,重定向地址欄會改變)
2)轉(zhuǎn)發(fā)只能轉(zhuǎn)發(fā)當前web應(yīng)用的資源,不能轉(zhuǎn)發(fā)到當前web應(yīng)用以外的資源沼溜。重定向可以訪問到其他應(yīng)用的資源平挑。(比如:https://www.baidu.com都可以的)
3)最重要的,轉(zhuǎn)發(fā)可以通過HttpServletRequest
來傳遞對象(request.setAttribute)系草,重定向不能通熄。
因為:重定向的原理是,立刻響應(yīng)一個302和location給用戶找都。重定向的request和setAttributes的request不是同一個唇辨。
結(jié)論:如果要使用request域?qū)ο筮M行數(shù)據(jù)共享,只能使用轉(zhuǎn)發(fā)技術(shù)能耻,不能使用重定向技術(shù)助泽。
request.getRequestDispatcher方法的作用是什么?
這一步之前的工作是對提交的request做處理嚎京,這一步(這句話)是表示:處理完了嗡贺,分發(fā)到下一個JSP頁面或者下一個Action繼續(xù)處理。
會有forward()和redirect()兩種情況鞍帝,forward()是request中的參數(shù)繼續(xù)傳遞诫睬,redirect()則是重新生成request了。