zoukankan      html  css  js  c++  java
  • 拦截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 }

      

  • 相关阅读:
    [持续交付实践] Jenkins 中国用户大会参会见闻
    [持续交付实践] 研发协作平台:从交付流水线到研发协作平台
    [持续交付实践] pipeline使用:Shared Libraries
    [持续交付实践] 交付流水线设计:分层自动化测试
    [持续交付实践] 交付流水线设计:安全专项测试
    openstack手动安装
    python threading模块2
    socket粗解
    python实现Telnet远程登陆到设备并执行命令
    Shell脚本学习
  • 原文地址:https://www.cnblogs.com/fanqisoft/p/10609577.html
Copyright © 2011-2022 走看看