使用SpringMVC开发Restful API(2)-使用Filter、Interceptor对请求进行拦截和处理拦截顺序

一 使用Filter拦截请求:

1.使用Filter拦截只需要我们定义一个类并实现javax.servlet.Filter接口,然后将其注册为bean即可。

示例:

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.stereotype.Component;

@Component
public class MyFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("MyFilter.init()");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        System.out.println("MyFilter.doFilter()");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter.destroy()");

    }

}

其中:

  init():方法会在Filter初始化的时候被调用。

  destroy():方法会在Filter销毁的时候被调用。

  doFilter():这是Filter中最重要的一个方法,这个方法会在每次过滤指定URL的时候被调用,其中,chain.doFilter(request, response)表示这个Filter过滤的URL是否需要发送给下一个Filter,如果不写,表示请求将在该Filter被拦截,不会往下执行,当然也不会进入ServletController

2.只是将一个Filter注册成一个Bean固然可用,但是他会拦截所有的URL,无法拦截指定的URL,当我们需要拦截指定URL时,我们还可以在配置类中注册FilterBean

示例:

@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new MyFilter());
        List<String> filterUrls = new ArrayList<>();
        filterUrls.add("/user/*");
        filterRegistrationBean.setUrlPatterns(filterUrls);
        return filterRegistrationBean;
    }
}

这样我们就可以用Filter拦截指定的URL

我们会发现,Filter虽然拦截了URL,但无法发现拦截的具体是哪个URL地址,也不知道调用了哪个Controller。想要知道拦截的具体是哪个URL地址,调用了哪个Controller,我们就得用到Interceptor

二  使用Interceptor拦截请求:

1.使用Interceptor我们只需要定义一个类并实现org.springframework.web.servlet.HandlerInterceptor接口。HandlerInterceptor有三个方法,具体作用如下:

  boolean preHandle()  这个方法会在进入具体Controller之前被调用,他的Object handler参数会记录这次请求会发送给哪个Controller,如果返回为true才会进入具体的Controller,否则会被拦截。

  postHandle()  这个方法会在具体的Controller方法处理完之后被调用,注意:如果Controller没有处理完就报了异常,那么这个方法就不会被调用。

  afterCompletion()  这个方法无论Controller有没有抛出异常都会被调用,如果抛出了异常,那么他的Exception ex参数会接收到异常信息。

示例:

@Component
public class MyInterceptor implements HandlerInterceptor{

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println(((HandlerMethod)handler).getMethod().getName());
        System.out.println("MyInterceptor.preHandle()");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor.postHandle()");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("MyInterceptor.afterCompletion()");
    }

}

仅仅是将Interceptor注册成Bean还不行,我们还得将该Bean添加到InterceptRegistry中,添加方法如下:

@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter{

    @Autowired
    private MyInterceptor myInterceptor;

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

}

这样一个Interceptor就完成了。

注意:标注了@ControllerAdvice的异常处理的Bean会在afterCompletion()方法之前捕获异常,如果@ControllerAdvice的类中的方法处理了该异常,那么异常就不会被传到afterCompletion()方法中,只有@ControllerAdvice的类中的方法没处理到该异常,那么该异常才会进入afterCompletion()方法的Exception ex参数中。

我们会发现Interceptor虽然可以知道具体会调用哪个Controller,但并不知道调用该Controller中的方法的具体入参是多少,想要知道入参是多少,得用到Aspect,具体请参见Spring核心功能之一之AOP。

三  SpringMVC处理拦截的的顺序为:Filter -> Interceptor -> ControllerAdvice -> Aspect -> Controller,异常返回的顺序则相反

原文地址:https://www.cnblogs.com/programmlover/p/10575631.html

时间: 2024-10-08 17:27:44

使用SpringMVC开发Restful API(2)-使用Filter、Interceptor对请求进行拦截和处理拦截顺序的相关文章

003 使用SpringMVC开发restful API

一:介绍说明 1.介绍 2.restful api的成熟度 二:编写Restful API的测试用例 1.引入spring的测试框架 在effective pom中查找 2.新建测试包,测试类 3.测试用例程序 1 package com.cao.web.controller; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.junit.runner.RunWith; 6 import org.springfr

004 使用SpringMVC开发restful API二

一:编写用户详情服务 1.任务 @PathVariable隐射url片段到java方法的参数 在url声明中使用正则表达式 @JsonView控制json输出内容 二:@PathVariable [email protected]小测试 测试类 1 @Test 2 public void whenGetInfoSuccess() throws Exception { 3 //发送请求 4 mockMvc.perform(MockMvcRequestBuilders.get("/user/1&qu

005 使用SpringMVC开发restful API二--处理创建请求

一:主要任务 1.说明 @RequestBody 映射请求体到java方法的参数 日期类型参数的处理 @Valid注解 BindingResult验证请求参数的合法性并处理校验结果 二:@RequestBody [email protected] 测试类 1 /** 2 * @throws Exception 3 * 4 */ 5 @Test 6 public void whenCreateSuccess() throws Exception { 7 String content="{\&quo

006 使用SpringMVC开发restful API四--用户信息的修复与删除,重在注解的定义

一:任务 1.任务 常用的验证注解 自定义返回消息 自定义校验注解 二:Hibernate Validator 1.常见的校验注解 2.程序 测试类 1 /** 2 * @throws Exception 3 * 更新程序,主要是校验程序的验证 4 * 5 */ 6 @Test 7 public void whenUpdateSuccess() throws Exception { 8 //JDK1.8的特性 9 Date date=new Date(LocalDateTime.now().pl

flask开发restful api

在此之前,向大家说明的是,我们整个框架用的是flask + sqlalchemy + redis.如果没有开发过web,还是先去学习一下,这边只是介绍如果从开发web转换到开发移动端.如果flask还不是很熟悉,我建议先到这个网站简单学习一下,非常非常简单.http://dormousehole.readthedocs.org/en/latest/ 一直想写一些特别的东西,能让大家学习讨论的东西.但目前网上的很多博客,老么就按照官方文档照本宣读,要么直接搬代码,什么都不说明.我写这个系列的博客,

开发restful api总结的几点小经验

与其说是开发,不如说是打补丁! 是个jesery+spring的restful service,加了一个权限校验部分,做了一些调整. 本来其实很简单的一个事,后来发现,这个代码太霸道.本来传个参数是action_id 这个东西,结果参数名字有如下:action_id,actionID,id 我只能说傻傻分不清楚到底你传的什么, 因为还有其他id,参数名字参考刚才的. 代码中的也是混乱,虽然我知道有很多先人在修改了,但是也不至于这样吧. 吐槽完毕. 1.N次开发restful api主意版本迭代,

SwaggerUI+SpringMVC——构建RestFul API的可视化界面

今天给大家介绍一款工具,这个工具目前可预见的好处是:自动维护最新的接口文档. 我们都知道,接口文档是非常重要的,但是随着代码的不断更新,文档却很难持续跟着更新,今天要介绍的工具,完美的解决了这个问题.而且,对于要使用我们接口的人来说,不需要在给他提供文档,告诉他地址,一目了然. 最近项目中一直有跟接口打交道,恰好又接触到了一个新的接口工具,拿出来跟大家分享一下. 关于REST接口,我在上篇文章中已经有介绍,这里来说一下如何配合SwaggerUI搭建RestFul API 的可视化界面.最终要达到

flask开发restful api系列(7)-蓝图与项目结构

如果有几个原因可以让你爱上flask这个极其灵活的库,我想蓝图绝对应该算上一个,部署蓝图以后,你会发现整个程序结构非常清晰,模块之间相互不影响.蓝图对restful api的最明显效果就是版本控制:而对整个项目来说,总要有后台管理系统吧,总要有web管理吧,但这些东西不能全部放到view.py.不单单是这样,如果你是一个经验丰富的程序员,你应该知道,一个程序最好只有一个入口点,从这个入口点进去,全是单向的,就像一棵树一样,入口点就在树根,然后蔓延到树干,树枝.树枝和树枝之间最好不要太多交集,也就

ASP.NET Core Web API 开发-RESTful API实现

REST 介绍: 符合REST设计风格的Web API称为RESTful API. 具象状态传输(英文:Representational State Transfer,简称REST)是Roy Thomas Fielding博士于2000年在他的博士论文 "Architectural Styles and the Design of Network-based Software Architectures" 中提出来的一种万维网软件架构风格. 目前在三种主流的Web服务实现方案中,因为R