使用Filter和Interceptor拦截REST服务(四)

在某些情况下,我们需要对REST API 做一些统一的处理 ,最常用的场景是我希望记录所有的REST API 处理的时间 ,那么如何的来实现这种需求呢?就需要用到这种RESTful API的拦截
过滤器( Filter )
拦截器( Interceptor)
切片( Aspect)

记录所有服务的处理时间

/**
 * 记录所有服务处理的时间
 * Created by ZhuPengWei on 2017/11/22.
 */
@Component
public class TimeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter初始化成功了");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        Long time = new Date().getTime();
        System.out.println("Filter方法执行前时间:" +time);
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Filter方法执行后时间:"+new Date().getTime()+ ",共耗时:"+(new Date().getTime()-time));
    }

    @Override
    public void destroy() {
        System.out.println("Filter销毁了");
    }
}

(1)、启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
(2)、每一次请求时都只调用方法doFilter()进行处理;
(3)、停止服务器时调用destroy()方法,销毁实例。

如果引用了第三方的过滤器,并且没有Conponent注解 怎么把第三方的过滤器引入到项目之中来呢?在传统的项目中一般有web.xml这个配置文件,在springboot之中一般是没有这个配置文件的

/**
 * Created by ZhuPengWei on 2017/11/22.
 */
@Configuration
public class WebConfig {
    @Bean
    public FilterRegistrationBean timeFilter() {
             // 过滤器注册
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
              // 时间过滤器
        TimeFilter timeFilter = new TimeFilter();
                 // 设置
        filterRegistrationBean.setFilter(timeFilter);
             List<String> urls = new ArrayList<String>();
               // 设置拦截路径
         urls.add("/*");
             filterRegistrationBean.setUrlPatterns(urls);
            return filterRegistrationBean;
    }
}

过滤器来拦截REST API 这种方式一般会有一个问题,这个问题是它只能拿到HTTP 的请求和响应,只能从请求和响应中获取一些参数,这些发过来的请求实际上是由哪一个控制器的哪一个方法来处理的在Filter中是不知道的,因为Filter这个接口是J2EE规范来定义的 在J2EE中实际上是不能了解到和Spring相关的任何东西。而自定义的比如说UserController实际上是springmvc自己定义的一些东西。
如果需要知道这些信息的话 我们需要第二个机制 拦截器 ,拦截器这个东西本身是spring框架提供的

/**
 * 时间拦截器
 * Created by ZhuPengWei on 2017/11/22.
 */
@Component
public class TimeInterceptor implements HandlerInterceptor {

// 1调用前
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("preHandle!!");
        System.out.println("拦截的类名称:"+ ((HandlerMethod)o).getBean().getClass().getName());
        System.out.println("拦截的方法名称:"+((HandlerMethod)o).getMethod().getName());
        // 设置拦截开始时间
        httpServletRequest.setAttribute("time",new Date().getTime());
        return true;
  }

// 2调用后
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
        Long nowTime = new Date().getTime();
        long preTime = (long) httpServletRequest.getAttribute("time");
        System.out.println("Interceptor耗时:" +(nowTime-preTime));
}

// 抛出异常 则 2不会被调用了  不管有没有抛出异常 3总是会被调用
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion");
        Long nowTime = new Date().getTime();
        long preTime = (long) httpServletRequest.getAttribute("time");
        System.out.println("Interceptor耗时:" +(nowTime-preTime));
        System.out.println(e);
        System.out.println("拦截之后");
    }
}
/**
 * 自定义过滤器 拦截器
 * 拦截器需要继承 WebMvcConfigurerAdapter
 * Created by ZhuPengWei on 2017/11/22.
 */
@Configuration
public class WebConfig  extends WebMvcConfigurerAdapter{

    @Autowired
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }


    @Bean
    public FilterRegistrationBean timeFilter() {
        // 过滤器注册
     FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        // 时间过滤器
     TimeFilter timeFilter = new TimeFilter();
        // 设置
     filterRegistrationBean.setFilter(timeFilter);
        List<String> urls = new ArrayList<String>();
        // 设置拦截路径
        urls.add("/*");
        filterRegistrationBean.setUrlPatterns(urls);
        return filterRegistrationBean;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Interceptor拦截器)是一个常用的Spring框架中的组件,用于在请求进入控制器之前或者响应返回到浏览器之前进行一些处理,比如校验用户登录状态、记录请求日志等。 在Spring中使用Interceptor非常简单,主要包括以下几个步骤: 1. 创建一个Interceptor类,实现HandlerInterceptor接口,并重写其中的三个方法:preHandle、postHandle和afterCompletion。preHandle在请求进入控制器之前执行,postHandle在控制器处理完请求后执行,afterCompletion在视图渲染完毕之后执行。 2. 在Spring的配置文件中配置Interceptor,可以通过<mvc:interceptors>标签配置全局的Interceptor,也可以通过实现WebMvcConfigurer接口来进行局部的Interceptor配置。 3. 配置完成后,Interceptor会自动拦截所有符合条件的请求,并按照preHandle、postHandle和afterCompletion的顺序执行。 下面是一个简单的Interceptor示例: ```java public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 校验用户登录状态 User user = (User) request.getSession().getAttribute("user"); if (user == null) { response.sendRedirect("/login"); return false; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 记录请求日志 System.out.println(request.getRequestURI() + " executed."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 清理资源等操作 } } ``` 在Spring的配置文件中配置Interceptor: ```xml <mvc:interceptors> <bean class="com.example.interceptor.LoginInterceptor" /> </mvc:interceptors> ``` 这样就可以实现一个简单的Interceptor拦截器了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值