1.ServletContext
Tomcat啓動的時候,需要識別webapps下的各個WEB應用,識別各個WEB應用的同時爲每個WEB應用創建對應的對象ServletContext,一個WEB應用對應一個ServletContext.每個ServletContext中都有一個很大的MAP,並且tomcat在啓動之初就向這個MAP中放入了大量的鍵值對的數據.當然我們也可以通過程序向這個大的MAP中放入鍵值對的數據.
注意:一個web應用對應唯一的一個ServletContext對象
ServletContext生命週期
同整個web應用的生命週期一致
1.1 ServletContext的作用
1.如何獲取ServletContext對象:
ServletContext servletContext=getServletContext();
2.多個Servlet之間共享數據 attribute:屬性
由於一個WEB應用只有一個ServletContext對象,當我們在訪問服務端的Servlet時,都可以在Servlet中獲取到當前應用唯一的ServletContext對象,所以可以利用ServletContext對象來實現共享數據.
3.獲取到WEB項目下指定資源
WEB項目的運行位置和源碼位置不在同一個位置,有時候我們需要獲取到WEB項目在
運行過程中,指定資源的真實路徑或者指定資源的輸入流,此時可以通過ServletContext來獲取?爲什麼可以獲取到?因爲ServletContext裏存放了當前web項目的路徑等信息.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
// 獲取服務端指定目錄下指定資源/目錄的真實路徑
String realPath = servletContext.getRealPath("/WEB-INF/config/conf.properties");
System.out.println(realPath);
// 獲取服務端指定目錄下指定文件的輸入流對象
InputStream is=
servletContext.getResourceAsStream("/WEB-INF/config/conf.properties");
Properties properties = new Properties();
properties.load(is);
System.out.println(properties.get("name"));
}
4.獲取到整個WEB全局的配置信息
我們之前在WEB中是爲Servlet配置過鍵值對的數據,這些數據只能在當前的Servlet中獲取到,如果希望配置一些參數,這些數據可以在所有Servlet都可以獲取到,此時我們可以爲當前應用配置全局的參數信息.配置方式如下:
<!--
全局的配置參數:所有的Servlet都可以獲取到的
局部的Servlet配置參數:當前的Servlet可以獲取到
-->
<context-param>
<param-name>username</param-name>
<param-value>mary</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>1234</param-value>
</context-param>
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
System.out.println(servletContext.getInitParameter("username"));
System.out.println(servletContext.getInitParameter("password"));
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
System.out.println(initParameterNames.nextElement());
}
}
5.獲取到文件的mime類型
我們每次向客戶端響應的內容類型可能是不一樣的.在講解HTTP協議那天,我們通過觀察網絡部分,發現如果本次響應的內容類型是一個HTML網頁,那麼在contentType消息頭中對應的值是:text/html;如果如果本次響應的內容類型是一個css文件.有時候用戶會下載我們服務端的不同資源,爲了讓瀏覽器更好的識別返回到客戶端的內容類型,我們要設置一下本次響應的內容類型,但問題是:計算機業界各種類型的文件是很多的,我們怎麼知道應該如何設置本次響應內容類型呢?就可以通過如下的API:
String value=ServletContext.getMimeType("333.avi");
ServletContext在tomcat/conf/web.xml中,根據文件後綴來查找本次響應內容是什麼.
2.Response對象
2.1 Request/Response生命週期
每次服務端獲取到來自客戶端的請求之後,解析HTTP請求部分,將HTTP請求部分封裝在HttpServletRequest對象中,同時創建HttpServletResponse對象, 之後在服務端完成本次響應之後,服務端就回收了剛纔創建好的Request,Response對象. 下次請求到達服務端,會分配新的HttpServletRequest/HttpServletResponse對象
Request/Response何時創建?何時銷燬?
總之:
HttpServletRequest對象代表的是從客戶端到服務端請求這個過程
HttpServletResponse代表從服務端到客戶端響應這個過程
2.2 HttpServletResponse對象的作用
既然HttpServletResponse代表從服務端到客戶端響應這個過程,而且結合協議我們知道
HTTP協議響應包含三大塊內容,分別是響應行,響應頭,響應體.
HttpServletResponse可以控制響應部分的三個部分
Response控制響應行
//控制響應行的狀態碼
response.setStatus(302);
response.sendError(404, "ni yao qiu qing de zi bu cun zai ");
Response控制響應頭
//測試利用response控制響應頭
response.setHeader("test", "0000");
1_實現重定向302+location,
2_一句話搞定 response.sendRedrect(”路徑”);
3_通過控制響應頭實現定時刷新
4_重定向/定時刷新
response控制響應體
PrintWriter out=response.getWriter();
out.println(“ssss”);
OutputStream os=response.getOuputStream();
os.print();
3.Request
3.1 生命週期
請求一次創建一次,請求結束,對象被回收
3.2 作用
1_獲取到請求部分三大塊,客戶端的部分信息IP
2_利用request實現請求轉發(重點),利用request中的MAP存儲數據
3.3 requestAPI
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 本次請求的方式: GET
String method = request.getMethod();
// 當前web路徑: /DynamicWebProject_war_exploded
String contextPath = request.getContextPath();
// 遠程客戶端的ip: 0:0:0:0:0:0:0:1
String remoteAddr = request.getRemoteAddr();
// 獲取header頭
String header = request.getHeader("name");
Enumeration<String> headerNames = request.getHeaderNames();
// 獲取請求體(表單參數)/路徑之後
String name = request.getParameter("name");
Enumeration<String> parameterNames = request.getParameterNames();
Map<String, String[]> parameterMap = request.getParameterMap();
String[] parameterValues = request.getParameterValues("");
}
4.請求轉發
4.1 什麼是請求轉發
當我們從客戶端向服務端AAServlet發起請求的時候,在AAServlet中沒有立即進行響應(即使在AAServlet中對客戶端進行響應也無法將內容響應到客戶端),而是將request/response繼續向後傳遞,傳遞到BBServlet,在BBServlet中完成了本次響應.
4.2 爲什麼要有請求轉發
因爲本次請求到服務端希望做一些事情,但是在AAServlet做這件事情不合適,將要實現的功能分爲2步來實現,一部分事情在AAServlet實現,剩餘部分在BBServlet實現
4.3 請求轉發本質是什麼
服務端有2個Servlet(AA,BB),AA執行完畢之後,執行BB,AA和BB共享同一對request/response
ps:請求轉發只能在當前項目內進行
public class ServletDemo04 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//向request中的名字爲attributes的MAP中放入數據
request.setAttribute("name01", "tom");
request.setAttribute("name02", "mary");
//向客戶端進行響應數據
response.getWriter().print("wo shi lai zi servletdemo04 de dai ma!");
//將request和response向後傳遞,傳遞給ServletDemo05 實現請求轉發
//通過request獲取到tomcat內部提供的API,叫做調度器對象
RequestDispatcher dispatcher = request.getRequestDispatcher("/ServletDemo05");
//dispatcher實現轉發操作 Tomcat通過/ServletDemo05路徑在WEB.XML找到對應全路徑名cn.itcast.test00.ServletDemo05
dispatcher.forward(request, response);
}
}
public class ServletDemo05 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以獲取到request中名稱爲attributes MAP中的數據
//獲取到request中名稱爲attributes MAP中的所有的key
Enumeration<String> names = request.getAttributeNames();
//遍歷names獲取到每個key
while(names.hasMoreElements()){
String key = names.nextElement();
Object value = request.getAttribute(key);
System.out.println(key+"<___>"+value);
}
//向客戶端進行響應
response.getWriter().print("wo shi serveltdemo05 zhong de dai ma!");
}
}
當我們訪問ServletDemo04時,結果如下