SpringBoot實現(xiàn)過濾器、攔截器與切片
過濾器Filter
過濾器概念
過濾器作用
Examples that have been identified for this design are
1) Authentication Filters, 即用戶訪問權(quán)限過濾
2) Logging and Auditing Filters, 日志過濾,可以記錄特殊用戶的特殊請求的記錄等
3) Image conversion Filters
4) Data compression Filters
5) Encryption Filters
6) Tokenizing Filters
7) Filters that trigger resource access events
8) XSL/T filters
9) Mime-type chain Filter
過濾器實現(xiàn)方式
import?org.slf4j.Logger;
import?org.slf4j.LoggerFactory;
import?org.springframework.stereotype.Component;
import?javax.servlet.*;
import?javax.servlet.http.HttpServletRequest;
import?java.io.IOException;
//?必須添加注解,springmvc通過web.xml配置
@Component
public?class?TimeFilter?implements?Filter?{
????private?static?final?Logger?LOG?=?LoggerFactory.getLogger(TimeFilter.class);
????@Override
????public?void?init(FilterConfig?filterConfig)?throws?ServletException?{
????????LOG.info("初始化過濾器:{}",?filterConfig.getFilterName());
????}
????@Override
????public?void?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?throws?IOException,?ServletException?{
????????LOG.info("start?to?doFilter");
????????long?startTime?=?System.currentTimeMillis();
????????chain.doFilter(request,?response);
????????long?endTime?=?System.currentTimeMillis();
????????LOG.info("the?request?of?{}?consumes?{}ms.",?getUrlFrom(request),?(endTime?-?startTime));
????????LOG.info("end?to?doFilter");
????}
????@Override
????public?void?destroy()?{
????????LOG.info("銷毀過濾器");
????}
????private?String?getUrlFrom(ServletRequest?servletRequest){
????????if?(servletRequest?instanceof?HttpServletRequest){
????????????return?((HttpServletRequest)?servletRequest).getRequestURL().toString();
????????}
????????return?"";
????}
}
在SpringBoot中注冊第三方過濾器
@Configuration
public?class?WebConfig?{
????/**
?????*?注冊第三方過濾器
?????*?功能與spring?mvc中通過配置web.xml相同
?????*?@return
?????*/
????@Bean
????public?FilterRegistrationBean?thirdFilter(){
????????ThirdPartFilter?thirdPartFilter?=?new?ThirdPartFilter();
????????FilterRegistrationBean?filterRegistrationBean?=?new?FilterRegistrationBean()?;
????????filterRegistrationBean.setFilter(thirdPartFilter);
????????List?urls?=?new?ArrayList<>();
????????//?匹配所有請求路徑
????????urls.add("/*");
????????filterRegistrationBean.setUrlPatterns(urls);
????????return?filterRegistrationBean;
????}
}
攔截器Interceptor
攔截器概念
攔截器作用
日志記錄:記錄請求信息的日志,以便進行信息監(jiān)控、信息統(tǒng)計、計算PV(Page View)等
權(quán)限檢查:如登錄檢測,進入處理器檢測檢測是否登錄
性能監(jiān)控:通過攔截器在進入處理器之前記錄開始時間,在處理完后記錄結(jié)束時間,從而得到該請求的處理時間。(反向代理,如apache也可以自動記錄);
通用行為:讀取cookie得到用戶信息并將用戶對象放入請求,從而方便后續(xù)流程使用,還有如提取Locale、Theme信息等,只要是多個處理器都需要的即可使用攔截器實現(xiàn)。
攔截器實現(xiàn)
@Component
public?class?TimeInterceptor?implements?HandlerInterceptor?{
????private?static?final?Logger?LOG?=?LoggerFactory.getLogger(TimeInterceptor.class);
????@Override
????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler)?throws?Exception?{
????????LOG.info("在請求處理之前進行調(diào)用(Controller方法調(diào)用之前)");
????????request.setAttribute("startTime",?System.currentTimeMillis());
????????HandlerMethod?handlerMethod?=?(HandlerMethod)?handler;
????????LOG.info("controller?object?is?{}",?handlerMethod.getBean().getClass().getName());
????????LOG.info("controller?method?is?{}",?handlerMethod.getMethod());
????????//?需要返回true,否則請求不會被控制器處理
????????return?true;
????}
????@Override
????public?void?postHandle(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler,?ModelAndView?modelAndView)?throws?Exception?{
????????LOG.info("請求處理之后進行調(diào)用,但是在視圖被渲染之前(Controller方法調(diào)用之后),如果異常發(fā)生,則該方法不會被調(diào)用");
????}
????@Override
????public?void?afterCompletion(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler,?Exception?ex)?throws?Exception?{
????????LOG.info("在整個請求結(jié)束之后被調(diào)用,也就是在DispatcherServlet?渲染了對應(yīng)的視圖之后執(zhí)行(主要是用于進行資源清理工作)");
????????long?startTime?=?(long)?request.getAttribute("startTime");
????????LOG.info("time?consume?is?{}",?System.currentTimeMillis()?-?startTime);
????}
//?java配置類
@Configuration
public?class?WebConfig?implements?WebMvcConfigurer?{
????@Autowired
????private?TimeInterceptor?timeInterceptor;
????@Override
????public?void?addInterceptors(InterceptorRegistry?registry){
????????registry.addInterceptor(timeInterceptor);
????}
}
節(jié)點信息。切片Aspect
切片概述
切片實現(xiàn)
docs.spring.io/spring/docs/5.0.12.RELEASE/spring-framework-reference/core.html#aop
@Aspect
@Component
public?class?TimeAspect?{
????private?static?final?Logger?LOG?=?LoggerFactory.getLogger(TimeAspect.class);
????@Around("execution(*?me.ifight.controller.*.*(..))")
????public?Object?handleControllerMethod(ProceedingJoinPoint?proceedingJoinPoint)?throws?Throwable{
????????LOG.info("切片開始。。。");
????????long?startTime?=?System.currentTimeMillis();
????????//?獲取請求入?yún)?/span>
????????Object[]?args?=?proceedingJoinPoint.getArgs();
????????Arrays.stream(args).forEach(arg?->?LOG.info("arg?is?{}",?arg));
????????//?獲取相應(yīng)
????????Object?response?=?proceedingJoinPoint.proceed();
????????long?endTime?=?System.currentTimeMillis();
????????LOG.info("請求:{},?耗時{}ms",?proceedingJoinPoint.getSignature(),?(endTime?-?startTime));
????????LOG.info("切片結(jié)束。。。");
????????return?null;
????}
}
過濾器、攔截器以及切片的調(diào)用順序



過濾器和攔截器的區(qū)別

參考
評論
圖片
表情
