Spring Boot 2.X(十):自定義註冊 Servlet、Filter、Listener

  • 2019 年 10 月 25 日
  • 筆記

前言

在 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 方法執行後執行。

示例程式碼

github

碼雲

非特殊說明,本文版權歸 朝霧輕寒 所有,轉載請註明出處.

原文標題:Spring Boot 2.X(十):自定義註冊 Servlet、Filter、Listener

原文地址:https://www.zwqh.top/article/info/17

如果文章對您有幫助,請掃碼關注下我的公眾號,文章持續更新中…

Exit mobile version