前言
在 Spring Boot 中已經移除了 web.xml 文件,如果需要注冊添加 Servlet、Filter、Listener 為 Spring Bean,在 Spring Boot 中有兩種方式:
- 使用 Servlet 3.0 API 的注解 @WebServlet、@WebFilter、@Listener 用來配置。
- Spring Boot JavaConfig 注解配置 Bean 的方式來進行配置。
注冊之前
在使用 Servlet 時,需要在 Spring Boot 入口類添加 @ServletComponentScan 注解,告訴 Spring Boot 去掃描使用下面注冊的 Servlet、Filter、Listener。
@SpringBootApplication
@ServletComponentScan
public class SpringBootServletApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootServletApplication.class, args);
}
}
注冊 Servlet
1.@WebServlet 屬性
屬性 | 類型 | 描述 |
---|---|---|
name | String | 指定Servlet名稱,等價於
|
value | String[] | 等同於 urlPatterns 屬性,兩者不應該同時使用 |
urlPatterns | String[] | 指定一組 Servlet 的 URL 匹配模式。等價於
|
loadOnStartup | int | 指定 Servlet 的加載順序,等價於
|
initParams | WebInitParam[] | 指定一組 Servlet 初始化參數,等價於
|
asyncSupported | boolean | 聲明 Servlet 是否支持異步操作模式,等價於
|
smallIcon | String | 此 Servlet 的小圖標 |
largeIcon | String | 此 Servlet 的大圖標 |
description | String | 該 Servlet 的描述信息,等價於
|
displayName | String | 該 Servlet 的顯示名,通常配合工具使用,等價於
|
2.示例
@WebServlet(urlPatterns = "/TestServlet")
public class TestServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = -3325041776508043481L;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
doPost(req, resp);
}
/*
* 實現請求uri和header打印,另外返回一個json
*/
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
System.out.println("RequestURI:" + req.getRequestURI());
System.out.println("Request Headers:");
StringBuilder sb = new StringBuilder();
Enumeration<?> names = req.getHeaderNames();
while (names.hasMoreElements()) {
String name = names.nextElement().toString();
Enumeration<?> hs = req.getHeaders(name);
sb.append(name).append(":");
while (hs.hasMoreElements()) {
sb.append(hs.nextElement()).append(";");
}
}
System.out.println(sb);
ObjectMapper om=new ObjectMapper();
UserEntity user=new UserEntity();
user.setId(1L);
user.setUserName("zwqh");
user.setUserSex("男");
user.setHeaders(sb.toString());
String resultJson=om.writeValueAsString(user);
resp.setContentType("application/json;charset=UTF-8");
resp.getWriter().print(resultJson);
}
}
其中@WebServlet(urlPatterns = "/TestServlet")等價於以下代碼:
<servlet>
<!-- 類名 -->
<servlet-name> TestServlet </servlet-name>
<!-- 所在的包 -->
<servlet-class> cn.zwqh.springbboot.servlet.TestServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name> TestServlet </servlet-name>
<!-- 訪問的url路徑地址 -->
<url-pattern> /TestServlet </url-pattern>
</servlet-mapping>
3.測試
瀏覽器訪問 http://127.0.0.1:8080/TestServlet
日志輸出:
注冊 Filter
1.@WebFilter 屬性
屬性 | 類型 | 描述 |
---|---|---|
filterName | String | 指定Filter名稱,等價於
|
value | String[] | 等同於 urlPatterns 屬性,兩者不應該同時使用 |
urlPatterns | String[] | 指定一組 Filter 的 URL 匹配模式。等價於
|
servletNames | String[] | 指定過濾器將應用於哪些 Servlet。取值於 @WebServlet 中的 name 屬性,或者是 web.xml 中
|
initParams | WebInitParam[] | 指定一組 Filter 初始化參數,等價於
|
dispatcherTypes | DispatcherType[] | 指定 Filter 的轉發模式,包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST |
asyncSupported | boolean | 聲明 Filter 是否支持異步操作模式,等價於
|
smallIcon | String | 此 Filter 的小圖標 |
largeIcon | String | 此 Filter 的大圖標 |
description | String | 該 Filter 的描述信息,等價於
|
displayName | String | 該 Filter 的顯示名,通常配合工具使用,等價於
|
2.示例
@WebFilter(urlPatterns = { "/TestServlet" }) // 注冊攔截器,並添加攔截路徑‘/TestServlet’
public class TestFilter implements Filter {
/**
* 初始化,只在項目啟動的時候執行一次
*/
@Override
public void init(FilterConfig filterConfig) {
System.out.println("===> TestFilter init");
}
/**
* 用於存放過濾器的業務邏輯實現代碼
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);// 處理請求和響應的分界線
System.out.println("===> chain.doFilter 后執行處理 response 的相關方法");
// 在response header里設置一個token
setToken(response);
}
private void setToken(ServletResponse response) {
HttpServletResponse res = (HttpServletResponse) response;
String token = UUID.randomUUID().toString();
res.setHeader("Token", token);
System.out.println("===> 設置了token:" + token);
}
/**
* 銷毀,在項目關閉,Servlet 容器銷毀前調用
*/
@Override
public void destroy() {
System.out.println("===> TestFilter destroy");
}
}
3.測試
瀏覽器訪問 http://127.0.0.1:8080/TestServlet :
日志打印:
4.Filter 主要使用場景
- 禁用瀏覽器的緩存(緩存的處理)
- 解決中文亂碼問題
- 登錄鑒權及權限管理
- 用戶授權,負責檢查用戶的請求,根據請求過濾用戶非法請求
- 日志記錄,詳細記錄某些特殊的用戶請求
- 其他場景
注冊 Listener
1.@Listener 屬性
屬性 | 類型 | 描述 |
---|---|---|
value | String | 偵聽器Listener的描述 |
2.示例
與 ServletContext 相關的監聽
Servlet 的監聽器 Listener 是實現了 javax.servlet.ServletContextListener 接口的服務器端程序,隨着 Web 應用啟動而啟動,只初始化一次,也隨着 Web 應用停止而銷毀。其主要作用是做一些初始化的內容添加工作,如參數和對象等。
@WebListener
public class ContextListener implements ServletContextListener, ServletContextAttributeListener{
public static final String INITIAL_CONTENT = "Content created in servlet Context";
/**
* ServletContext創建
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("===> context initialized");
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("content", INITIAL_CONTENT);
}
/**
* ServletContext銷毀
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("===> context destroyed");
}
/**
* context屬性新增
*/
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("===> context attribute added");
}
/**
* context屬性移除
*/
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("===> context attribute removed");
}
/**
* context屬性替換
*/
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("===> context attribute replaced");
}
}
與 HttpSession 相關的監聽
@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionIdListener, HttpSessionAttributeListener,
HttpSessionActivationListener {
/**
* session被創建時
*/
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("===> session created");
}
/**
* session被銷毀時
*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("===> session destroyed");
}
/**
* sessionId改變
*/
@Override
public void sessionIdChanged(HttpSessionEvent se, String oldSessionId) {
System.out.println("===> session id changed");
}
/**
* session屬性新增
*/
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("===> session attribute added");
}
/**
* session屬性移除
*/
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("===> session attribute removed");
}
/**
* session屬性替換
*/
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("===> session attribute replaced");
}
/**
* session的鈍化,內存的數據寫入到硬盤上的過程。
*/
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("===> session will passivate");
}
/**
* session的活化,將硬盤的數據恢復到內存中。
*/
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("===> session did activate");
}
}
與 ServletRequest 相關的監聽
@WebListener
public class RequestListener implements ServletRequestListener,ServletRequestAttributeListener {
/**
* 請求即將進入Web應用程序的范圍/請求初始化時
*/
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("===> request initialized");
}
/**
* 請求即將進入Web應用程序的范圍/請求銷毀時
*/
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("===> request destroyed");
}
/**
* request屬性新增
*/
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("===> request attribute added");
}
/**
* request屬性移除
*/
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("===> request attribute removed");
}
/**
* request屬性替換
*/
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println("===> request attribute replaced");
}
}
3.項目相關日志輸入(啟動和停止)
先執行 contextInitialzed 方法在執行 TestFilter 類的 init 方法,
contextDestroyed 方法在 TestFilter 類 destroy 方法執行后執行。
示例代碼
非特殊說明,本文版權歸 朝霧輕寒 所有,轉載請注明出處.
原文標題:Spring Boot 2.X(十):自定義注冊 Servlet、Filter、Listener
原文地址: https://www.zwqh.top/article/info/17
如果文章對您有幫助,請掃碼關注下我的公眾號,文章持續更新中...