本篇內容主要講解“Springboot實現攔截器的方式有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Springboot實現攔截器的方式有哪些”吧!
一、攔截器方式
1、配置HandlerInterceptor
2、注冊攔截器
3、使用攔截器的坑
二、過濾器方式
1、實現Filter接口
2、使用過濾器需要注意的
實現過濾請求有兩種方式:
一種就是用攔截器,一種就是過濾器
攔截器相對來說比較專業,而過濾器雖然不專業但是也能完成基本的攔截請求要求。
下面這個也是我們公司項目攔截器的寫法,總體來說感覺還不錯,我就記錄了下來。
利用了一個靜態Pattern變量存儲不走攔截器的路徑,然后在preHandle方法當中進行過濾,讓他返回true。
@Component
public class LoginInterceptor implements HandlerInterceptor{
private static final Pattern SHOULD_NOT_FILTER_URL_PATTERN;
static {
List<String> urlList = new ArrayList<>();
// 將不走攔截器的請求存放到Pattern
urlList.add("(socket/.*)");
urlList.add("(user/findUserList)");
StringBuilder sb = new StringBuilder();
for (String url : urlList) {
sb.append(url);
sb.append("|");
}
sb.setLength(sb.length() - 1);
SHOULD_NOT_FILTER_URL_PATTERN = Pattern.compile(sb.toString());
}
/**
* 在請求處理之前進行調用(Controller方法調用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
// 獲取訪問的url
String servletPath = request.getServletPath();
// 排除特定請求
if (SHOULD_NOT_FILTER_URL_PATTERN.matcher(servletPath).find()) {
return true;
}
if (session.getAttribute("user") != null) {
// 可能有的項目在校驗完session,還會校驗token
String token = request.getHeader("access_token");
// 此處業務省略。。。
return true;
}
return false;
}
/**
* 請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
/**
* 在整個請求結束之后被調用,也就是在DispatcherServlet 渲染了對應的視圖之后執行(主要是用于進行資源清理工作)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}配置完上面的攔截器還需要注冊攔截器。
WebMvcConfigurerAdapter類是 Spring內部的一種配置方式
采用JavaBean的形式來代替傳統的xml配置文件形式進行針對框架個性化定制
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多個攔截器組成一個攔截器鏈
// addPathPatterns 用于添加攔截規則
// excludePathPatterns 用戶排除攔截
registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}繼承WebMvcConfigurerAdapter 重寫addInterceptors方法的時候,一定要使用注入方式,將loginInterceptor注入到變量當中,要么就使用@Bean注解的方式,將loginInterceptor(攔截器)注入到容器。
之所以這么搞是因為攔截器在 Bean 初始化之前進行,所以在攔截器中無法像這樣注入 Bean。
就算加了@Component,他是存放于容器當中了,但是他存放容器當中的對象屬性,是空屬性。

在WebMvcConfigurerAdapter 使用@Autowired注入了一遍攔截器,屬性就有值了。
說白了不管采用哪種方案,目的只有一個,讓對象的屬性有值,因為攔截器比其他對象初始化早,導致屬性為空,想讓他有值,就想辦法讓他重新走一遍spring注入容器,也可以采用這種方式:
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
// 這么寫的目的是為了在SessionInterceptor中能注入spring中的service
@Bean
LoginInterceptor loginInterceptor() {
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多個攔截器組成一個攔截器鏈
// addPathPatterns 用于添加攔截規則
// excludePathPatterns 用戶排除攔截
registry.addInterceptor(loginInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}本人這一篇博客寫了關于filter的一些知識:http://www.dadijd.cn/article/204084.htm
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Component;
@Component
@WebFilter(filterName = "requestParamFilter",urlPatterns = "/*")
public class RequestParamFilter implements Filter {
private static final Pattern SHOULD_NOT_FILTER_URL_PATTERN;
static {
List<String> urlList = new ArrayList<>();
// 將不走攔截器的請求存放到Pattern
urlList.add("(socket/.*)");
urlList.add("(user/findUserList)");
StringBuilder sb = new StringBuilder();
for (String url : urlList) {
sb.append(url);
sb.append("|");
}
sb.setLength(sb.length() - 1);
SHOULD_NOT_FILTER_URL_PATTERN = Pattern.compile(sb.toString());
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
// 發送請求會執行這個方法
// 一個doFilter相當于攔截器的執行前和執行后
// filterChain.doFilter后面的內容就是執行后的內容,假如不執行filterChain.doFilter方法相當于方法被攔截
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("sunhan---請求參數過濾器!---test1");
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpSession session = request.getSession();
// 獲取訪問的url
String servletPath = request.getServletPath();
// 排除特定請求
if (SHOULD_NOT_FILTER_URL_PATTERN.matcher(servletPath).find()) {
filterChain.doFilter(servletRequest,servletResponse);
}
System.out.println("開始攔截了................");
//業務代碼
}
@Override
public void destroy() {
}
}攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器里注入一個service,可以調用業務邏輯
執行順序如下:

到此,相信大家對“Springboot實現攔截器的方式有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。