JavaWeb - Tomcat&Http&Servlet
JavaWeb - Tomcat&Http&Servlet
目錄1 Tomcat
1.1 軟體架構
-
C/S架構 - client/server
- 優點:體驗好
- 缺點:對客戶端和伺服器都進行維護
-
B/S架構 - browser/server
- 特殊的c/s架構
- 優點:維護簡單,因為通過瀏覽器直接訪問不需要下載客戶端
- 體驗稍差
1.2 資源的分類
-
靜態資源:
- 同一資源不同使用者看到同樣內容
- html,js,css
-
動態資源:
- 瀏覽器只能解析靜態資源,響應前需要轉換(tomcat)
- 同一資源不同使用者看到不同內容
- jsp,aspx,php
1.3 URL請求路徑
Uniform Resource Locator 統一資源定位符,網際網路上資源有唯一URL
格式:
協議://域名:埠號/資源位置?引數=值
- 協議:http,https,ftp
- 域名或IP地址,訪問web資源
- 埠號:程式需要埠讓另一臺計算機訪問,http預設埠80
- 資源位置:web資源在伺服器上的位置
- 引數=值:瀏覽器和伺服器互動傳遞的資料
常見web伺服器:
- Tomcat - 58%
- JBoss/WildFly - 20%
- Jetty - 10%
- Glassfish - 5.55%
- Weblogic - 2.8%
1.4 Tomcat的內容目錄
1.4.1 內容目錄
1.4.2 啟動關閉Tomcat指令碼
1.4.3 Tomcat啟動報錯
-
1 視窗彈出一閃而過
- 需配置好Java環境變數 - JAVA_HOME
-
2 8080埠被佔用
- 2.1 找到佔用埠相關程序並殺死程序
- 2.2 修改Tomcat埠號
- 3 如需啟動兩個tomcat除了設定該位置兩個不同的埠
- 還需修改關閉埠
- 4 啟動日誌亂碼問題
1.5 Tomcat專案釋出三種方式
1.5.1 webapps部署
- 熱部署,不需要重啟Tomcat即可更新資源
- 更新需要在該目錄下使用更新後的專案替換
1.5.2 server.xml 部署
- 在該檔案中
標籤中新增 標籤 - 配置檔案修改完成後,需要重啟生效
1.5.3 獨立xml部署
- 在tomcat/Catalina/localhost 目錄下建立xml檔案並新增
標籤 - 支援熱部署
1.6 IDE配置Tomcat
1.6.1 專案結構
1.6.2 頁面資源熱更新
2 Http
2.1 Http協議
2.1.1 特點:
- 基礎協議:TCP協議
- 預設埠號:80埠
- 基於請求/響應模型:請求和響應成對出現,先請求後響應
- 無狀態協議:各請求間相互獨立,不能互動資料
2.1.2 版本
- Http/1.0 傳送請求,建立一次連線,獲得一個web資源,連線斷開
- 每次請求都是一個新的連線,根據TCP建立
- Http/1.1 傳送請求,建立一次連線,獲得多個web資源,連線斷開
- 長連線,多個請求可以複用同一個連線
2.1.3 報文格式
請求報文:客戶端傳送給伺服器端的報文
響應報文:伺服器端返回給客戶端的報文
2.1.3.1 請求報文
格式:請求行,請求頭,空行,請求體
請求行:
- 請求方式
- 協議規定7種,常用2種(get和post)
- get 請求引數拼接在URL後不安全
- URL長度限制get請求資料的大小
- 無請求體
- post請求資料大小沒有限制,且請求引數安全
- URL
- 協議版本
請求頭:key:value對
-
http協議型別,編碼,傳送內容長度等
-
Referer:直接訪問沒有,轉發則告訴請求來自何處
-
Cookie:存放瀏覽器快取cookie資訊
-
User-Agent:瀏覽器與作業系統資訊
空行
請求體:表單 POST方式提交的資料(請求引數)
- 多值使用&連線
2.1.3.2 響應報文
格式:響應行,響應頭,空行,響應體
響應行:
- 協議/版本
- 狀態碼
- 200:請求成功
- 302:請求重定向
- 304:訪問本地快取
- 404:請求資源不存在
- 500:伺服器內部錯誤,通常程式拋異常
- 狀態碼描述
響應頭:
- Location:指定響應的路徑,與302狀態碼搭配使用完成跳轉
- Content-Desposition:檔案下載時使用,以下載的方式解析正文
- Set-Cookie:伺服器向瀏覽器寫入Cookie
- Refresh:定時重新整理
空行
響應體:返回給瀏覽器的資料
3 Servlet
3.1 概述
介面,類想被瀏覽器訪問需要實現該介面
接受請求,處理邏輯,響應結果
3.2 快速實現
-
web專案
-
java類實現業務邏輯並實現servlet介面
-
web.xml種配置url-pattern:通過反射機制建立該物件並呼叫該物件裡service方法
-
精確匹配
-
目錄匹配:/aa/*
-
字尾匹配:*.xxx 比如 *.do
-
部署web專案
3.3 生命週期
預設生命週期
-
開啟Tomcat不會建立例項
-
第一次訪問該servlet建立例項(單例項)並呼叫init方法
-
接著呼叫service方法
-
之後每次請求訪問都通過該例項建立執行緒訪問
-
伺服器關閉,servlet銷燬執行destory方法
-
可以通過配置
在啟動tomcat是例項化servlet物件,預設值是-1,不自動建立,建議數值4-N
體系結構
介面 Servlet:頂級介面,提供5個宣告方法
|
抽象類 GenericServlet:抽象類,只需重寫service方法即可
|
抽象類 HttpServlet:抽象類,處理http協議中的互動(請求,響應),根據不同請求方式做出處理,重寫doGet和doPost方法
3.4 Request物件
Tomcat將HTTP請求所有資訊都封裝到Request物件中
Request物件API獲取請求行,請求頭,請求體
接收請求引數中文亂碼:
- get: tomcat8及以上,內部URL編碼(UTF-8),不會中文亂碼
- post:
- 客戶端(瀏覽器)編碼:UTF-8
- 伺服器預設解碼:ISO-8859-1 拉丁文
- setCharacterEncoding("UTF-8"); 方法內首行
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取請求行
System.out.println("請求方式"+req.getMethod());
System.out.println("專案名"+req.getContextPath());
System.out.println("URL"+req.getRequestURI());
System.out.println("協議版本"+req.getProtocol());
System.out.println("IP"+req.getRemoteAddr());
System.out.println("--------------------------------------------");
//獲取請求頭
System.out.println(req.getHeader("Host"));
//獲取請求頭所有資訊
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String s = headerNames.nextElement();
System.out.println(s+":"+req.getHeader(s));
}
System.out.println("--------------------------------------------");
//獲取請求引數
System.out.println("使用者名稱"+req.getParameter("username"));
//獲取多個值的引數
String[] hobbies = req.getParameterValues("hobby");
System.out.print("hobby: ");
for (String hobby : hobbies) {
System.out.print(hobby+" ");
}
System.out.println();
//獲取所有
Map<String, String[]> parameterMap = req.getParameterMap();
parameterMap.forEach((k,v)->{
System.out.print(k+":");
for (String s : v) {
System.out.print(s+" ");
}
System.out.println();
});
System.out.println("--------------------------------------------");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
doGet(req,resp);
}
}
3.5 請求轉發
API:
-
request物件獲取轉發器物件
- RequestDispatcher getRequestDispatcher(String path)//要跳轉到的資源路徑
-
轉發器物件實現轉發
- void forward(ServletRequest request, ServletResponse response)
特點:
- 瀏覽器:發出一次請求
- 位址列:沒有變化
- 轉發只能是伺服器內部資源
3.6 Request域物件
API:
-
設定資料
- void setAttribute(String naem)
-
獲取資料
- Object getAttribute(String name)
-
刪除資料
- void removeAttribute(String name)
生命週期:
- 建立:使用者傳送請求,建立request
- 銷燬:伺服器返回響應,銷燬request
- 範圍:一次請求,包含多次轉發
3.7 Response物件
體系結構:
ServletResponse 介面
|
HttpServletResponse 介面
|
org.apache.catalina.connector.ResponseFacade 實現類(tomcat提供)
響應行:
API:
- 設定狀態碼
- void setStatus(int sc)
響應頭:
API:
- 設定指定頭名稱和值
- void setHeader(String name,String value)
響應體:
API:
-
字元輸出流
- PrintWriter getWriter()
-
位元組輸出流
- ServletOutputStream getOutputStream()
同一servlet種兩種輸出流不能同時存在
3.8 響應重定向
方式一:
-
設定狀態嗎
- response.setStatus(302);
-
設定響應頭Location
- response.setHeader("Location","重定向的網路地址")
方式二:
response.sendRedirect("重定向的網路地址")
特點:
- 位址列會發生改變
- 重定向是而此請求
- 客戶端(瀏覽器行為),可跳轉到伺服器外部資源
- 不能用request域共享資料
中文亂碼:伺服器 ISO-8859-1 瀏覽器GBK
-
第一種方式:指定伺服器響應編碼方式,寫在首行
- resp.setCharacterEncoding("GBK")
-
第二種方式:統一瀏覽器和伺服器編碼
- resp.setContentType("text/html;charset=utf-8")
3.9 ServletContext 物件
3.9.1 作用
- 域物件(共享資料)
- 獲取資源在伺服器的真實地址
- 獲取全域性的引數配置
- 獲取問MIME型別
3.9.2 獲取方式
-
request物件獲取
- req.getServletContext();
-
基層HttpServlet後直接呼叫
- this.getServletContext();
3.9.3 域物件
API:
-
儲存資料
- void setAttribute(String name, Object value)
-
獲取資料
- Object getAttribute(String name)
-
刪除資料
- void removeAttribue(String name)
範圍:
當前專案範圍,多個servlet可共享
3.9.4 獲取資源在伺服器真實地址
API:傳入專案下的對映路徑,獲取真實路徑
- String getRealPath(String path);
3.9.5 獲取全域性配置引數
<context-param>
<param-name>username</param-name>
<param-value>guanyu</param-value>
</context-param>
req.getServletContext().getInitParameter("username")
3.9.6 獲取MIME型別
格式:大型別/小型別
- text/html image/jpeg
req.getServletContext().getMimeType(".jpg")