Tomcat基本使用
目錄結(jié)構(gòu)
Tomcat是一個(gè)小型的輕量級(jí)應(yīng)用服務(wù)器。其下載和安裝比較簡(jiǎn)單,去官網(wǎng)下載之后解壓即可使用,注意前提是需要配置好了java環(huán)境變量,在此不再贅述。下圖是Tomcat的目錄結(jié)構(gòu):
Tomcat的啟動(dòng):進(jìn)入bin目錄,雙擊startup.bat即可啟動(dòng)。
部署項(xiàng)目
方式一:直接發(fā)布(不常用)。把項(xiàng)目文件夾拷貝到webapps目錄下,瀏覽器地址欄輸入:服務(wù)器所在ip地址:8080/項(xiàng)目名/資源路徑
方式二:用虛擬路徑的方式發(fā)布項(xiàng)目。具體步驟如下:
- 在tomcat/conf目錄下新建一個(gè)Catalina目錄(如果已經(jīng)存在就無(wú)需創(chuàng)建);
- 在Catalina目錄下創(chuàng)建localhost目錄(如果已經(jīng)存在就無(wú)需創(chuàng)建);
- 在localhost中創(chuàng)建xml配置文件,名稱自擬,注意這個(gè)名稱,是瀏覽器訪問(wèn)路徑,也就是虛擬路徑
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="這里寫上項(xiàng)目的真實(shí)路徑">
- 在瀏覽器輸入:服務(wù)器所在ip地址:8080/虛擬路徑/資源路徑
方式三:在IDEA中集成Tomcat。具體操作就是在web項(xiàng)目中配置Edit Configuration。如果想通過(guò)虛擬路徑進(jìn)行訪問(wèn),可以在Edit Configuration中的Deployment選項(xiàng)中配置Artifact。如果想在服務(wù)器運(yùn)行時(shí)就打開(kāi)指定頁(yè)面比如hello.html,需要在web目錄下的web-inf下的web.xml中的web-app標(biāo)簽下增加以下內(nèi)容:
<welcome-file-list>
<welcome-file>hello.html</welcome-file>
</welcome-file-list>
Servlet核心知識(shí)
Servlet接口并不是jdk中的接口,所以我們需要引入jar,Tomcat中提供了jar包。
手動(dòng)引入:web項(xiàng)目是在WEB-INF的lib中存放jar包,所以先創(chuàng)建lib目錄在WEB-INF下。我們需要引入的jar包在tomcat安裝目錄下的lib下。
自動(dòng)引入:在IDEA中ProjectStructure-Modules-Dependencies中引入依賴就行。
Servlet的編寫步驟
- 寫一個(gè)類,實(shí)現(xiàn)Servlet接口(在后面了解了Servlet體系結(jié)構(gòu)之后,就知道一般用繼承HttpServlet類來(lái)完成這個(gè)類)
- 配置servlet的映射路徑(訪問(wèn)路徑),具體如下:
a. 方式一:配置文件方式配置servlet的映射路徑,在web.xml配置文件中配置【不是自己寫的Servlet或者jar包中的Servlet、框架中的Servlet需要使用配置文件進(jìn)行配置】:
(1)配置servlet標(biāo)簽:
servlet-name:和servlet標(biāo)簽中的servlet-name保持一致.
servlet-class:要配置的servlet的全限定名
(2)配置servlet-mapping標(biāo)簽
url-pattern:就是要配置的servlet的映射路徑(就是給客戶端訪問(wèn)的路徑),
它有三種配置方式:
1、全路徑匹配(精確匹配,常用):例如"/demo01"那么訪問(wèn)的時(shí)候,就要以該路徑訪問(wèn),注意千萬(wàn)不要少了斜杠/;
2、目錄匹配(模糊匹配,很少使用):例如"/\*",那么訪問(wèn)該servlet的時(shí)候,任意路徑都能訪問(wèn);
3、擴(kuò)展名匹配(很少使用):例如"\*.do",那么只要以.do結(jié)尾的請(qǐng)求,都能訪問(wèn)到這個(gè)servlet。
b. 方式二:注解方式配置servlet的映射路徑,使用WebServlet注解進(jìn)行配置【自己寫的Servlet可以用注解配置】
Servlet的執(zhí)行原理
思考:為什么在瀏覽器輸入地址就能訪問(wèn)到Servlet的service() ?
比如虛擬地址配置為web01,訪問(wèn)資源為的demo01,在地址欄輸入:localhost:8080/web01/demo01,訪問(wèn)的最終結(jié)果是調(diào)用了ServletDemo01類中的service()方法。在服務(wù)器中所發(fā)生的事情是:
找到項(xiàng)目,識(shí)別“/demo01”路徑,如果路徑是靜態(tài)資源路徑,就會(huì)找到Tomcat中內(nèi)置的一個(gè)Servlet即DefaultServlet,由DefaultServlet把靜態(tài)資源響應(yīng)給客戶端;如果路徑不是靜態(tài)資源路徑,(以配置文件方式為例,)就會(huì)去解析web.xml配置文件,根據(jù)servlet-mapping標(biāo)簽中的url-pattern找到同級(jí)別的servlet-name,再去servlet標(biāo)簽下找到servlet-name同一級(jí)別的servlet-class,這樣就獲取了ServletDemo01類的全限定名,有了全限定類名,就可以根據(jù)反射創(chuàng)建Servlet對(duì)象,并再根據(jù)反射調(diào)用service()方法。
Servlet的生命周期
Servlet的生命周期:就是從servlet創(chuàng)建出來(lái),一直到servlet對(duì)象銷毀的整個(gè)過(guò)程就是servlet的生命周期。
- servlet什么時(shí)候創(chuàng)建出來(lái):默認(rèn)是第一次有請(qǐng)求訪問(wèn)這個(gè)servlet的時(shí)候創(chuàng)建,創(chuàng)建出來(lái)之后會(huì)將servlet的對(duì)象存儲(chǔ)到tomcat容器中(Servlet對(duì)象只會(huì)創(chuàng)建一次)。
能否配置這個(gè)servlet在服務(wù)器啟動(dòng)的時(shí)候創(chuàng)建呢?是可以的:
如果通過(guò)配置文件進(jìn)行配置的時(shí)候,通過(guò)<load-on-startup>1或其他正整數(shù)</load-on-startup>標(biāo)簽配置。其實(shí)init()方法就是配置了<load-on-startup>1</load-on-startup>。如果通過(guò)注解方式進(jìn)行配置,通過(guò)loadOnStartup屬性進(jìn)行配置。 - servlet什么時(shí)候銷毀:當(dāng)服務(wù)器關(guān)閉的時(shí)候
servlet的生命周期方法:在servlet的整個(gè)生命周期中,會(huì)執(zhí)行到的方法:
- init():會(huì)在servlet對(duì)象被初始化出來(lái)的時(shí)候調(diào)用,只調(diào)用一次
- service():會(huì)在servlet每次接收到請(qǐng)求的時(shí)候調(diào)用,可調(diào)用多次
- destroy():會(huì)在servlet對(duì)象被銷毀之前調(diào)用,只調(diào)用一次
ServletConfig對(duì)象
用于獲取servlet配置時(shí)候的初始化參數(shù),一般在框架中使用。
比如SpringMVC中有一個(gè)DispatcherServlet類,它有一個(gè)作用是去掃描項(xiàng)目中的某個(gè)包里面的所有類,比如項(xiàng)目com.wjun.controller包中,有很多類,我們想讓DispatcherServlet掃描這個(gè)包中的所有類,但是肯定不能在DispatcherServlet里面把包名寫死,因?yàn)槠渌?xiàng)目還要使用這個(gè)框架。所以就可以通過(guò)配置文件配置,來(lái)告訴DispatcherServlet要掃描的包名。比如如下配置文件,要怎么告訴DispatcherServlet呢?就是通過(guò)servletConfig對(duì)象。
<!--配置當(dāng)前servlet的初始化參數(shù)-->
<init-param>
<param-name>package</param-name>
<param-value>com.wjun.controller</param-value>
</init-param>
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
/**
* @author Wjun
*/
public class HelloServlet extends HttpServlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//使用ServletConfig對(duì)象讀取初始化參數(shù)
String packageName = servletConfig.getInitParameter("package");
System.out.println("init方法被調(diào)用了" + packageName);
}
}
Servlet的體系結(jié)構(gòu)

如果實(shí)現(xiàn)Servlet接口,必須實(shí)現(xiàn)所有方法,且功能較少;
如果繼承GenericServlet抽象類,功能較少;
通常繼承HttpServlet抽象類,在http協(xié)議下使用servlet重寫doGet和doPost方法。
Servlet的常用編寫方法:
- 寫一個(gè)類繼承HttpServlet,重寫doGet和doPost方法
(1) doGet方法:是處理來(lái)自客戶端的get請(qǐng)求
(2) doPost方法:是處理來(lái)自客戶端的post請(qǐng)求
通常情況下,服務(wù)器端針對(duì)同一個(gè)請(qǐng)求(不同的請(qǐng)求方式)不會(huì)做不同的處理。所以我們會(huì)選擇在doGet中調(diào)用doPost - 配置servlet的映射路徑
ServletContext概述
ServletContext是一個(gè)全局對(duì)象,上下文對(duì)象。服務(wù)器為每一個(gè)應(yīng)用(項(xiàng)目)都創(chuàng)建了一個(gè)ServletContext對(duì)象。ServletContext屬于整個(gè)應(yīng)用,不局限于某個(gè)Servlet。
ServletContext的作用:
- 作為域?qū)ο蟠嫒?shù)據(jù),讓Servlet共享,利用了setAttribute()和getAttribute()
- 獲得文件MIME類型
- 獲得全局初始化參數(shù):web.xml中<context-param>標(biāo)簽中的<param-name>和<param-value>
- 獲取web資源路徑-真實(shí)路徑
使用字節(jié)輸入流,獲取文件路徑的方式:
方法1. 使用FileInputStream(磁盤絕對(duì)路徑);此時(shí)參數(shù)使用磁盤路徑
方法2. 使用ClassLoader將文件轉(zhuǎn)換成流,xx類名.class.getClassLoader().getResourceAsStream(文件名); 前提是,文件需要在resources目錄中(即類路徑,編譯后的路徑)
方法3:使用ServletContext的getServletContext()可以獲取web里面的資源的真實(shí)路徑,然后再將其作為參數(shù)傳給FileInputStream來(lái)獲取。
方法4:使用ServletContext的getResourceAsStream(文件名); 前提是,文件需要在resources目錄中(即類路徑,編譯后的路徑)
總結(jié):在web項(xiàng)目中,將文件轉(zhuǎn)換成流,有兩種方式:
1 如果文件在resources里面,使用類加載器
2 如果文件在web里面,使用ServletContext