拦截RESTful API并做相应处理的方式

⒈使用Filter(过滤器)

 1 package cn.coreqi.security.filter;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 import javax.servlet.*;
 6 import java.io.IOException;
 7 import java.util.Date;
 8 
 9 @Component
10 public class TimeFilter implements Filter {
11     @Override
12     public void init(FilterConfig filterConfig) throws ServletException {
13         System.out.println("TimeFilterc初始化完成!");
14     }
15 
16     @Override
17     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
18         long start = new Date().getTime();
19         filterChain.doFilter(servletRequest,servletResponse);
20         System.out.println("执行方法所用时间:" + (new Date().getTime() - start));
21     }
22 
23     @Override
24     public void destroy() {
25         System.out.println("TimeFilterc已释放!");
26     }
27 }

  当然,如果是你自己写的Filter一般都会这样,别人的Filter就没有办法使用@Component注解了,那么你可以使用Web.xml,当然SpringBoot没有这个,可以使用SpringBoot独有的方式。

 1 package cn.coreqi.security.config;
 2 
 3 import cn.coreqi.security.filter.TimeFilter;
 4 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 5 import org.springframework.context.annotation.Bean;
 6 import org.springframework.context.annotation.Configuration;
 7 
 8 import java.util.ArrayList;
 9 import java.util.List;
10 
11 @Configuration
12 public class WebConfig {
13     @Bean
14     public FilterRegistrationBean timeFilter(){
15         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
16         filterRegistrationBean.setFilter(new TimeFilter());
17         List<String> urls = new ArrayList<>();
18         urls.add("/*");
19         filterRegistrationBean.setUrlPatterns(urls);
20         return filterRegistrationBean;
21     }
22 }

 

遗憾的是,Filter是Servlet提供的,SpringMVC的一些信息没有办法全部拿到,只能拿到request和response,没有办法拿到是那个控制器,那个方法处理的。这种情况下可以考虑Spring提供的Interceptor(拦截器)。

⒉使用Interceptor(拦截器)

 1 package cn.coreqi.security.interceptor;
 2 
 3 import org.springframework.stereotype.Component;
 4 import org.springframework.web.method.HandlerMethod;
 5 import org.springframework.web.servlet.HandlerInterceptor;
 6 import org.springframework.web.servlet.ModelAndView;
 7 
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 @Component
12 public class TimeInterceptor implements HandlerInterceptor {
13     /**
14      * 在控制器方法调用之前执行
15      * @param request
16      * @param response
17      * @param handler   当前控制器方法
18      * @return
19      * @throws Exception
20      */
21     @Override
22     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
23         System.out.println(((HandlerMethod) handler).getBean().getClass().getName());
24         System.out.println(((HandlerMethod) handler).getMethod().getName());
25         return true;
26     }
27 
28     /**
29      * 在控制器方法调用之后执行,如果控制器方法抛出了异常,那么该方法将不会被调用
30      * @param request
31      * @param response
32      * @param handler
33      * @param modelAndView
34      * @throws Exception
35      */
36     @Override
37     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
38 
39     }
40 
41     /**
42      * 无论控制器方法是否抛出异常,该方法始终会被调用
43      * @param request
44      * @param response
45      * @param handler
46      * @param ex
47      * @throws Exception
48      */
49     @Override
50     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
51 
52     }
53 }
 1 package cn.coreqi.security.config;
 2 
 3 import cn.coreqi.security.filter.TimeFilter;
 4 import cn.coreqi.security.interceptor.TimeInterceptor;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 7 import org.springframework.context.annotation.Bean;
 8 import org.springframework.context.annotation.Configuration;
 9 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
10 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
11 
12 import java.util.ArrayList;
13 import java.util.List;
14 
15 @Configuration
16 public class WebConfig implements WebMvcConfigurer {
17 
18     @Autowired
19     private TimeInterceptor timeInterceptor;
20 
21     @Bean
22     public FilterRegistrationBean timeFilter(){
23         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
24         filterRegistrationBean.setFilter(new TimeFilter());
25         List<String> urls = new ArrayList<>();
26         urls.add("/*");
27         filterRegistrationBean.setUrlPatterns(urls);
28         return filterRegistrationBean;
29     }
30 
31     @Override
32     public void addInterceptors(InterceptorRegistry registry) {
33         registry.addInterceptor(timeInterceptor);
34     }
35 }

 拦截器可以拿到请求、响应、处理请求控制器方法的对象,但没法拿到处理请求方法参数的值。如果想要更进一步的拿到具体参数的值,那么就需要用到切片。

⒊使用Aspect(切片)

1         <dependency>
2             <groupId>org.springframework.boot</groupId>
3             <artifactId>spring-boot-starter-aop</artifactId>
4         </dependency>
 1 package cn.coreqi.security.aspect;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 import org.aspectj.lang.annotation.Around;
 5 import org.aspectj.lang.annotation.Aspect;
 6 import org.springframework.stereotype.Component;
 7 
 8 @Aspect //声明当前类为切片类
 9 @Component  //让切片成为Spring容器中的一部分
10 public class TimeAspect {
11 
12     /**
13      * 第一个*代表任何返回值
14      * cn.coreqi.security.controller.UserController.*   代表拦截该类(控制器)中的所有方法
15      * (..)代表该方法可以有任意参数
16      * @param pjp   表示当前所拦截的信息
17      * @return
18      */
19     @Around("execution(* cn.coreqi.security.controller.UserController.*(..))")
20     public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
21         for (Object arg:pjp.getArgs()){ //遍历拦截方法的参数列表
22             System.out.println("arg is :" + arg);
23         }
24         Object object = pjp.proceed();  //调用真正的方法
25         return object;
26     }
27 }

 

  

posted @ 2019-03-27 18:22  SpringCore  阅读(632)  评论(0编辑  收藏  举报