JavaWeb
Java Web 元件
首先獻上Tomcat架構神圖:
Servlet
-
Servlet容器:
執行在Web伺服器上的程式,作為來自HTTP客戶端的請求和HTTP伺服器上的資料庫或應用程式之間的中間層,它負責處理使用者的請求,並根據請求生成相應的返回資訊提供給使用者。
大體原理圖如下:
- Servlet請求的處理過程:
- 瀏覽器發起http請求
- Servlet容器收到請求後,分別建立了HttpServletRequest物件和HttpServletResponse物件
- Servlet容器呼叫HttpServlet的init方法,init方法只在第一次請求時被呼叫
- Servlet容器讀取HttpServletRequest物件中讀取資訊,然後透過service()方法處理請求資訊,根據請求資訊找到對應的路由(業務邏輯)
- 處理完後將處理資訊封裝到HttpServletResponse物件,然後返回
- 容器關閉時,呼叫destory函式
- Servlet生命週期
-
伺服器啟動時(web.xml中配置load-on-startup=1,預設為0)或者第一次請求該servlet時,就會初始化一個Servlet物件,也就是會執行初始化方法init(ServletConfig conf)。
-
servlet物件去處理所有客戶端請求,在service(ServletRequest req,ServletResponse res)方法中執行
-
伺服器關閉時,銷燬這個servlet物件,執行destroy()方法。
-
由JVM進行垃圾回收。
Filter
- Filter過濾器:
Filter也稱為過濾器,主要功能是在HttpServletRequest物件到達Servlet之前,攔截、檢查該物件,同時也可以對該HttpServletRequest物件的頭部資料進行相應的修改;同時,也會攔截HttpServletResponse,修改物件中的資料
通俗來講就是用來過濾網站資料,用於處理中文亂碼、登入驗證等操作...
- Filter工作原理:
1、Filter 程式是一個實現了特殊介面的 Java 類,與 Servlet 類似,也是由 Servlet 容器進行呼叫和執行的。
2、當在 web.xml 註冊了一個 Filter 來對某個 Servlet 程式進行攔截處理時,它可以決定是否將請求繼續傳遞給 Servlet 程式,以及對請求和響應訊息是否進行修改。
3、當 Servlet 容器開始呼叫某個 Servlet 程式時,如果發現已經註冊了一個 Filter 程式來對該 Servlet 進行攔截,那麼容器不再直接呼叫 Servlet 的 service 方法,而是呼叫 Filter 的 doFilter 方法,再由 doFilter 方法決定是否去啟用 service 方法。
4、但在 Filter.doFilter 方法中不能直接呼叫 Servlet 的 service 方法,而是呼叫 FilterChain.doFilter 方法來啟用目標 Servlet 的 service 方法,FilterChain 物件時透過 Filter.doFilter 方法的引數傳遞進來的。
5、只要在 Filter.doFilter 方法中呼叫 FilterChain.doFilter 方法的語句前後增加某些程式程式碼,這樣就可以在 Servlet 進行響應前後實現某些特殊功能。
6、如果在 Filter.doFilter 方法中沒有呼叫 FilterChain.doFilter 方法,則目標 Servlet 的 service 方法不會被執行,這樣透過 Filter 就可以阻止某些非法的訪問請求。
- 生命週期:
Listener
監聽,當涉及某個介面的操作時,會呼叫相關函式
-
ServletContextListener:對Servlet上下文的建立和銷燬進行監聽; ServletContextAttributeListener:監聽Servlet上下文屬性的新增、刪除和替換;
-
HttpSessionListener:對Session的建立和銷燬進行監聽。Session的銷燬有兩種情況,一箇中Session超時,還有一種是透過呼叫Session物件的invalidate()方法使session失效。
-
HttpSessionAttributeListener:對Session物件中屬性的新增、刪除和替換進行監聽;
-
ServletRequestListener:對請求物件的初始化和銷燬進行監聽; ServletRequestAttributeListener:對請求物件屬性的新增、刪除和替換進行監聽。
Maven
存在的必要性
- 手動匯入:
點選專案結構
然後選擇路徑匯入
- 使用Maven匯入
我們可以透過pom.xml中編寫xml條目統一匯入庫
配置
- 去官網下載,這不用說了吧
- 編輯環境變數
去Maven官網下載,然後編輯環境變數
- 配置映象源
在conf/setting.xml中寫入
- 配置倉庫地址
同樣位置下寫入如下條目
- 在IDEA中配置Maven
使用
pom.xml:Maven的核心配置檔案,記錄該專案的資訊
Maven的相關功能及其IDEA UI下的相關操作演示
一個專案中一般包含三個模組:生命週期、外掛、依賴
Tomcat
Tomcat主要功能
tomcat作為web伺服器,主要有兩個核心元件
Connector(聯結器): HTTP伺服器功能,進行Socket通訊(基於TCP/IP),解析HTTP報文
Container(容器):Servlet容器功能:載入和管理Servlet,由Servlet具體負責處理Request請求
Connector聯結器
Connector由如下元件構成:
- EndPoint:進行socket通訊,將位元組寫入位元組的輸入流中然後傳給Processor,或者將位元組輸出流轉化成位元組
- Processor:將位元組流物件轉成Request物件,或者將Response物件轉成位元組流物件
- Adapter:將Request物件解析成ServletRequest物件
Endpoint與Processor有一個組合名稱為ProtocolHandler
Container容器
在Container中有四種容器:
- Engine 表示整個 Catalina 的 Servlet 引擎,用來管理多個虛擬站點,一個 Service 最多隻能有一個 Engine,但是一個引擎可包含多個 Host
- Host 代表一個虛擬主機,或者說一個站點,可以給 Tomcat 配置多個虛擬主機地址,而一個虛擬主機下可包含多個 Context
- Context 表示一個 Web 應用程式,每一個Context都有唯一的path,一個Web應用可包含多個 Wrapper
- Wrapper 表示一個Servlet,負責管理整個 Servlet 的生命週期,包括裝載、初始化、資源回收等
JavaWeb元件 + Tomcat 開發
Servlet
(嚴重踩坑:注意Tomcat + Servlet + Java 的版本匹配問題,可以參考:https://tomcat.apache.org/whichversion.html)
使用方法如下:
-
繼承
HttpServlet
抽象類,然後重寫doGet
等方法 -
註冊Servlet,路由對映:
-
在高版本的Servlet中可以使用@WebServlet註解指明路由
-
低版本中在web.xml中註冊Servlet,然後宣告對應路由
-
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet()
public class HelloServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter(); // 響應流
writer.print("Hello,Serlvet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
web.xml
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Filter
Filter:過濾器,用來過濾網站的資料
- 處理中文亂碼
- 登入驗證
Filter:
package filter;
import javax.servlet.*;
import java.io.IOException;
import javax.servlet.Filter;
public class TestFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException{
System.out.println("Test Filter Init");
System.out.println(System.currentTimeMillis());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException{
servletResponse.getWriter().write("Before TestFilter:\n");
System.out.println("Before TestFilter:");
System.out.println(System.currentTimeMillis());
filterChain.doFilter(servletRequest, servletResponse);
servletResponse.getWriter().write("After TestFilter\n");
System.out.println("After TestFilter");
System.out.println(System.currentTimeMillis());
}
public void destroy(){
System.out.println("Test Filter Destroy");
System.out.println(System.currentTimeMillis());
}
}
web.xml
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>filter.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/show</url-pattern>
</filter-mapping>
Listener
步驟:
- 實現監聽器的介面
- 在web.xml中配置路由
實現介面:
package listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineCountListener implements HttpSessionListener {
// 建立session監聽(session建立時會觸發這個函式)
public void sessionCreated(HttpSessionEvent sessionEvent) {
System.out.println("SessionCreated");
// 獲取session上下文
ServletContext ctx = sessionEvent.getSession().getServletContext();
// 讀
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(onlineCount == null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
// 寫
ctx.setAttribute("OnlineCount",onlineCount);
}
// 銷燬session監聽(session銷燬時會觸發這個函式)
public void sessionDestroyed(HttpSessionEvent sessionEvent){
System.out.println("SessionDestroyed");
ServletContext ctx = sessionEvent.getSession().getServletContext();
// 讀
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(onlineCount == null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
// 寫
ctx.setAttribute("OnlineCount",onlineCount);
}
}
web.xml
<listener>
<listener-class>listener.OnlineCountListener</listener-class>
</listener>
參考文獻
- https://github.com/Y4tacker/JavaSec/blob/main/5.記憶體馬學習/Tomcat/Tomcat介紹/Tomcat介紹.md#connector聯結器