springboot攔截器HandlerInterceptor詳解


    Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。

HandlerInterceptor 的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之后、視圖渲染之前以及request全部結束之后。我們不能通過攔截器修改request內容,但是可以通過拋出異常(或者返回false)來暫停request的執行。

實現 UserRoleAuthorizationInterceptor 的攔截器有:

ConversionServiceExposingInterceptor 
 
CorsInterceptor 
 
LocaleChangeInterceptor 
 
PathExposingHandlerInterceptor
  
ResourceUrlProviderExposingInterceptor 
 
ThemeChangeInterceptor 
 
UriTemplateVariablesHandlerInterceptor 
 
UserRoleAuthorizationInterceptor

其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比較常用。

 

配置攔截器也很簡單,Spring 為什么提供了基礎類WebMvcConfigurerAdapter ,我們只需要重寫 addInterceptors 方法添加注冊攔截器。

 

實現自定義攔截器只需要3步: 

1、創建我們自己的攔截器類並實現 HandlerInterceptor 接口。 

2、創建一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors 方法。 

2、實例化我們自定義的攔截器,然后將對像手動添加到攔截器鏈中(在addInterceptors方法中添加)。 

PS:本文重點在如何在Spring-Boot中使用攔截器,關於攔截器的原理請大家查閱資料了解。

代碼示例:

package com.kfit.interceptor;
  
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
  
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
  
/**
 * 自定義攔截器1
 *
 * @author   Angel
 */
publicclass MyInterceptor1 implements HandlerInterceptor {
  
    @Override
    publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println(">>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)");
  
        returntrue;// 只有返回true才會繼續向下執行,返回false取消當前請求
    }
  
    @Override
    publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println(">>>MyInterceptor1>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)");
    }
  
    @Override
    publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println(">>>MyInterceptor1>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)");
    }
  
}

 

com.kfit.interceptor.MyInterceptor2.java

package com.kfit.interceptor;
  
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
  
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
  
/**
 * 自定義攔截器2
 *
 * 
 */
public class MyInterceptor2 implements HandlerInterceptor {
  
    @Override
    publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println(">>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)");
  
        returntrue;// 只有返回true才會繼續向下執行,返回false取消當前請求
    }
  
    @Override
    publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println(">>>MyInterceptor2>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)");
    }
  
    @Override
    publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println(">>>MyInterceptor2>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)");
    }
  
}

 

Com.kfit.config.MyWebAppConfigurer.java

package com.kfit.config;
  
import com.kfit.interceptor.MyInterceptor1;
import com.kfit.interceptor.MyInterceptor2;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  
@Configuration
public class MyWebAppConfigurer
        extends WebMvcConfigurerAdapter {
  
    @Override
    publicvoid addInterceptors(InterceptorRegistry registry) {
        // 多個攔截器組成一個攔截器鏈
        // addPathPatterns 用於添加攔截規則
        // excludePathPatterns 用戶排除攔截
        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
        registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
  
}

 


然后在瀏覽器輸入地址: http://localhost:8080/index 后,控制台的輸出為:

>>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)
>>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)
>>>MyInterceptor2>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)
>>>MyInterceptor1>>>>>>>請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)
>>>MyInterceptor2>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)
>>>MyInterceptor1>>>>>>>在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用於進行資源清理工作)
---------------------

HandlerInterceptor攔截登陸的實現

@Component
public class MyHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String name= (String) request.getSession().getAttribute("LoginName");
        if (!name.isEmpty()){
            request.getRequestDispatcher("/main.html").forward(request,response);
            return false;
        }else {
            request.getRequestDispatcher("/login.html").forward(request, response);
            return true;
        }
    }
}

實現攔截方法從而判斷使否含有Session值 該方法在請求之前執行
@Controller
public class HelloController {
    @RequestMapping("login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session){
        if (username.equals("123")&password.equals("123")){
            session.setAttribute("LoginName",username);
            return "redirect:main";
        }else{
            return "login";
        }
    }
--------------------- 
作者:小灬羅 
來源:CSDN 
原文:https://blog.csdn.net/luojingwei1997/article/details/80554672 
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM