上一篇咱們學習了 spring boot 利用Controller響應數據與響應頁面。 通常的Web開發使用 Controller 基本上能夠完成大部分需求,可是有的時候咱們仍是會用到 Servlet、Filter、Listener 等等。html
在spring boot中添加本身的Servlet、Filter、Listener有兩種方法java
- 代碼註冊: 經過ServletRegistrationBean、 FilterRegistrationBean 和ServletListenerRegistrationBean 得到控制。
- 註解註冊: 在SpringBootApplication 上使用@ServletComponentScan註解後,Servlet、Filter、Listener 能夠直接經過 @WebServlet、@WebFilter、@WebListener 註解自動註冊,無需其餘代碼。
spring boot 中註冊servlet
代碼註冊
- 建立Servlet類:AaServlet.java。
public class AaServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost()"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<h1>AaServlet</h1>"); } }
- 經過ServletRegistrationBean註冊。
//Project2Application.java @Bean public ServletRegistrationBean AaServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(new AaServlet()); registration.addUrlMappings("/a"); return registration; }
- 運行測試。
訪問:http://localhost:8080/aspring
![](http://static.javashuo.com/static/loading.gif)
註解註冊
- 建立Servlet類:BbServlet.java。
@WebServlet(urlPatterns = "/b") public class BbServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost()"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<h1>BbServlet</h1>"); } }
- 添加註解@ServletComponentScan。
@ServletComponentScan @SpringBootApplication public class Project2Application { public static void main(String[] args) { SpringApplication.run(Project2Application.class, args); } @Bean public ServletRegistrationBean AaServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(new AaServlet()); registration.addUrlMappings("/a"); return registration; } }
- 運行測試。
訪問:http://localhost:8080/b瀏覽器
![](http://static.javashuo.com/static/loading.gif)
filter 和 listener的註冊和servlet同樣。這裏就很少說了。app
接下來講一下攔截器。ide
自定義攔截器
Spring提供了HandlerInterceptor(攔截器)。它的功能跟過濾器相似,可是提供更精細的的控制能力:在request被響應以前、request被響應以後、視圖渲染以前以及request所有結束以後。咱們不能經過攔截器修改request內容,可是能夠經過拋出異常(或者返回false)來暫停request的執行。oop
spring boot提供了一些攔截器,咱們能夠直接拿來使用,好比:post
- ConversionServiceExposingInterceptor
- CorsInterceptor
- LocaleChangeInterceptor
- PathExposingHandlerInterceptor
- ResourceUrlProviderExposingInterceptor
- ThemeChangeInterceptor
- UriTemplateVariablesHandlerInterceptor
- UserRoleAuthorizationInterceptor
咱們也能夠本身定義攔截器,定義攔截器的步驟大體分爲:學習
一、建立咱們本身的攔截器類並實現 HandlerInterceptor 接口。
二、建立一個Java類繼承WebMvcConfigurerAdapter,並重寫addInterceptors 方法。
三、實例化咱們自定義的攔截器,而後將對像手動添加到攔截器鏈中(在addInterceptors方法中添加)。測試
咱們來親自試一下:
- 建立咱們本身的攔截器
//MyInterceptor2 public class MyInterceptor1 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1==========>在請求處理以前進行調用(Controller方法調用以前)"); return true;// 只有返回true纔會繼續向下執行,返回false取消當前請求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor1==========>請求處理以後進行調用,可是在視圖被渲染以前(Controller方法調用以後)"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor1==========>在整個請求結束以後被調用,也就是在DispatcherServlet 渲染了對應的視圖以後執行(主要是用於進行資源清理工做)"); } }
//MyInterceptor2 public class MyInterceptor2 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor2==========>在請求處理以前進行調用(Controller方法調用以前)"); return true;// 只有返回true纔會繼續向下執行,返回false取消當前請求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor2==========>請求處理以後進行調用,可是在視圖被渲染以前(Controller方法調用以後)"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor2==========>在整個請求結束以後被調用,也就是在DispatcherServlet 渲染了對應的視圖以後執行(主要是用於進行資源清理工做)"); } }
建立一個Java類繼承WebMvcConfigurerAdapter,並重寫addInterceptors 方法,添加攔截器。
//MyWebAppConfigurer @Configuration public class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { // 多個攔截器組成一個攔截器鏈 // addPathPatterns 用於添加攔截規則 // excludePathPatterns 用戶排除攔截 registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**"); registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**"); super.addInterceptors(registry); } }
測試:運行項目,隨便訪問一個路徑,好比http://localhost:8080/test
瀏覽器會報錯,不用管,看控制檯。
![](http://static.javashuo.com/static/loading.gif)
攔截器已經起做用了。
值得注意的是:只有通過DispatcherServlet 的請求,纔會走攔截器鏈,咱們自定義的Servlet 請求是不會被攔截的,好比咱們自定義的Servlet地址是不會被攔截器攔截的。
可是過濾器不一樣。無論是屬於哪一個Servlet 只要複合過濾器的過濾規則,過濾器都會攔截。
本篇文章就先介紹到這裏,若是哪裏講的不明白,請及時與我聯繫。
參考文章:Spring Boot 攔截器
做者:cleverfan連接:https://www.jianshu.com/p/fba5c0fd09bb來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。