RESTful API的攔截方式 (過濾器Filter)攔截器(Interceptor)切片(Aspect)
阿新 • • 發佈:2020-11-28
優先順序按排序
1 過濾器(Filter) 最先進入攔截,只能獲取到response,request
2 攔截器(Interceptor) 可以獲取到執行的類名,方法名
3 切片(Aspect) 可以獲取到引數
具體使用哪一個看業務需求吧.
1 過濾器(Filter)
自定義Filter
package com.imooc.web.filter; import org.springframework.stereotype.Component; import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @Component // 增加一個註解即可使用,不需要其他配置,會攔截所有請求 public class TimeFilter implements Filter { @Override public void destroy() { System.out.println("time filter destroy"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("time filter start"); long start = new Date().getTime(); chain.doFilter(request, response); // 繼續執行程式,不呼叫doFilter 不會往下執行 System.out.println("time filter 耗時:"+ (new Date().getTime() - start)); System.out.println("time filter finish"); } @Override public void init(FilterConfig arg0) throws ServletException { // 程式啟動會載入 System.out.println("time filter init"); } }
如果是引用第三方的Filter 使用方法:
package com.imooc.web.config; import java.util.ArrayList; import java.util.List; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.imooc.web.filter.TimeFilter; @Configuration public class WebConfig { @Bean public FilterRegistrationBean timeFilter() { // 註冊第三方Filter FilterRegistrationBean registrationBean = new FilterRegistrationBean(); TimeFilter timeFilter = new TimeFilter(); registrationBean.setFilter(timeFilter); // 需要攔截的url List<String> urls = new ArrayList<>(); urls.add("/*"); registrationBean.setUrlPatterns(urls); return registrationBean; } }
2 攔截器(Interceptor)
2.1自定義Interceptor
package com.imooc.web.interceptor; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class TimeInterceptor implements HandlerInterceptor { // 先進入該方法 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); System.out.println(((HandlerMethod)handler).getBean().getClass().getName()); System.out.println(((HandlerMethod)handler).getMethod().getName()); request.setAttribute("startTime", new Date().getTime()); return true; // 返回true才能繼續執行controller } // 如果Controller方法丟擲了異常,不會進入該方法 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); Long start = (Long) request.getAttribute("startTime"); System.out.println("time interceptor 耗時:"+ (new Date().getTime() - start)); } // 不管方法是不是丟擲異常 都會進入該方法 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); Long start = (Long) request.getAttribute("startTime"); System.out.println("time interceptor 耗時:"+ (new Date().getTime() - start)); System.out.println("ex is "+ex); } }
2.2 注入自定義的Interceptor
package com.imooc.web.config; import com.imooc.web.interceptor.TimeInterceptor; import org.springframework.beans.factory.annotation.Autowired; 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 TimeInterceptorConfig extends WebMvcConfigurerAdapter { // 自定義的Interceptor @Autowired private TimeInterceptor timeInterceptor; // 注入spring @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(timeInterceptor); } }
3 切片(Aspect)
自定義切片
package com.imooc.web.aspect; import java.util.Date; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class TimeAspect { // 切入具體的方法,攔截UserController的所有方法 @Around("execution(* com.imooc.web.controller.UserController.*(..))") public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("time aspect start"); Object[] args = pjp.getArgs(); // 可以獲取方法引數 for (Object arg : args) { System.out.println("arg is "+arg); } long start = new Date().getTime(); Object object = pjp.proceed(); // 繼續往下執行Controller System.out.println("time aspect 耗時:"+ (new Date().getTime() - start)); System.out.println("time aspect end"); return object; } }