其他分享
首页 > 其他分享> > SpringBoot之WebMvcConfigurer拦截器的常用使用详解

SpringBoot之WebMvcConfigurer拦截器的常用使用详解

作者:互联网

目录

1.引入pom依赖

  • 因为用到拦截器的 几乎都是web项目,引入下web包 拦截器对象也在web包里
  • thymeleaf: 查看静态界面;

    <!--引入springboot父工程依赖-->
    <!--引入依赖作用:
    可以省去version标签来获得一些合理的默认配置
    -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>

    <dependencies>
        <!--引入含有WebMvcConfigurer的包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!--模板引擎 -用于查看界面-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

    </dependencies>


2. 启动类配置

  • 只需要注意下 其它的类都要在启动类同包或及下层目录即可 让@SpringBootApplication中@ComponentScan扫描到;
  • 如果类不在同级目录或下层目录 可以用@Import(Xxx.class)引入;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/*HandlerInterceptor启动类*/
@SpringBootApplication
public class InterceptorTestAppliction {
    public static void main(String[] args) {
        SpringApplication.run(InterceptorTestAppliction.class, args);
    }
}


3.resources包下数据

  • 主要测试拦截器相应的几个功能,它们的内容并不重要;

4.HandlerInterceptor 自定义拦截器实例配置

  • 三个方法的运行顺序为: preHandle -> postHandle -> afterCompletion;
  • 如果preHandle返回值为false,三个方法仅运行preHandle;
  • 如果运行拦截放行后的代码出错,则不会执行postHandle;
  • 自定义拦截器实例需要实现HandleInterceptor接口;
  • 注入到 ioc 自定义拦截器配置需要使用到 拦截器实例;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//自定义拦截器
//自定义拦截器需要实现HandleInterceptor接口
@Component
public class MyInterceptor implements HandlerInterceptor {
    //处理器运行之前执行
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        System.out.println("前置运行----a1");
        //返回值为false将拦截原始处理器的运行
        //如果配置多拦截器,返回值为false将终止当前拦截器后面配置的拦截器的运行
        System.out.println(handler);
        return true;
    }

    //处理器运行之后执行
    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("后置运行----b1");
        System.out.println(handler);
        System.out.println(modelAndView);
    }

    //所有拦截器的后置执行全部结束后,执行该操作
    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) throws Exception {
        System.out.println("完成运行----c1");
        System.out.println(handler);
        System.out.println(ex);
    }

    //三个方法的运行顺序为    preHandle -> postHandle -> afterCompletion
    //如果preHandle返回值为false,三个方法仅运行preHandle
}


5.WebMvcConfigurer 自定义拦截器配置

  • WebMvcConfigurer是一个接口,提供例如跨域设置、自定义的拦截器、类型转化器等等
  • 跨域这方面,我并不打算用拦截器来做 用网关的过滤器会更好,这里就开阔下思路 拦截器 也能做跨域设置

5.1 启用并注册自定义拦截器实例

  • 将拦截器实例 从ioc获取出来 将拦截器当作入参传入InterceptorRegistry();
  • 一定要指定拦截器路径和排除拦截路径;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

//自定义拦截器
@Configuration
public class WebConfigurer implements WebMvcConfigurer {


    @Autowired //把你写的自定义拦截器实例注入进来
    private MyInterceptor myInterceptor;

    // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //创建InterceptorRegistration对象并将自定义拦截器传入;
        InterceptorRegistration interceptorRegistration = registry.addInterceptor(myInterceptor);
        //addPathPatterns方法(指定拦截路径,往往使用 "/**")
        interceptorRegistration.addPathPatterns("/**");
        //Bean加载的时候有先后顺序 默认也是0 和@Order(0) 一个作用
        interceptorRegistration.order(0);
        //excludePathPatterns方法(指定排除拦截路径,用于登录等部分开放接口)
        interceptorRegistration.excludePathPatterns("/mhh/Interceptor/excludeInterceptorTest");

        /**
         * 与此拦截器一起使用的路径匹配器实现。
         * 这是一个可选的高级属性,只有在使用自定义路径匹配器实现时才需要,
         * 该实现支持映射元数据,而默认情况下不支持Ant路径模式。
         */

//        interceptorRegistration.pathMatcher(new PathMatcher() {
//            @Override
//            public boolean isPattern(String s) {
//                return false;
//            }
//
//            @Override
//            public boolean match(String s, String s1) {
//                return false;
//            }
//
//            @Override
//            public boolean matchStart(String s, String s1) {
//                return false;
//            }
//
//            @Override
//            public String extractPathWithinPattern(String s, String s1) {
//                return null;
//            }
//
//            @Override
//            public Map<String, String> extractUriTemplateVariables(String s, String s1) {
//                return null;
//            }
//
//            @Override
//            public Comparator<String> getPatternComparator(String s) {
//                return null;
//            }
//
//            @Override
//            public String combine(String s, String s1) {
//                return null;
//            }
//        });
//        registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/register");
    }
}    


5.11 拦截器测试

  • 正常访问–interceptorTest:进入拦截器–preHandle()–>进入要访问的方法–interceptorTest()–>进入拦截器–postHandle()–>进入拦截器–afterCompletion–>返回页面;
  • 排除–excludeInterceptorTest:它不会进入拦截器 正常进入—>然后返回;
  • 代码出错访问–exceptionTest:进入拦截器–preHandle()–>进入要访问的方法–exceptionTest()–>代码出错–>进入拦截器–afterCompletion–>返回页面 (它不会走拦截器postHandle()方法)
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/mhh/interceptor")
public class InterceptorTestController {

    @RequestMapping("interceptorTest/{id}")
    public String InterceptorTest(@PathVariable("id") String docId){
        return docId;
    }

    @RequestMapping("excludeInterceptorTest")
    public String excludeInterceptorTest(){
        return "排除测试";
    }
    @RequestMapping("exceptionTest")
    public void exceptionTest(){
        throw new RuntimeException("测试异常错误");
    }
}



5.2 自定义资源映射

  • classpath:表示项目绝对目录
  • file:表示本地绝对目录
  • 映射路径末尾必须加:/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

//自定义拦截器
@Configuration
public class WebConfigurer implements WebMvcConfigurer {

    // 自定义资源映射
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // 添加静态资源路径,然后跟项目的路径进行映射

        //addResourceHandler为添加映射路径。
        //addResourceLocations为添加资源路径。
        //file:表示本地绝对目录
        registry.addResourceHandler("/mhh/interceptor/document/*").addResourceLocations("file:///D:/doc/");

        //addResourceHandler为添加映射路径。
        //addResourceLocations为添加资源路径。
        //classpath:表示项目绝对目录
        registry.addResourceHandler("/mhh/interceptor/js/*").addResourceLocations("classpath:static/js/");
    }

}    

5.21 自定义资源映射测试

  • file:表示本地绝对目录
  • 可以看出访问的是: http://localhost:8080/mhh/interceptor/document/aa.png
                   映射的是:   D:/doc/aa.png

在这里插入图片描述


  • classpath:表示项目相对目录
  • 可以看出访问的是:http://localhost:8080/mhh/interceptor/js/jquery.js
           实际访问的是:static/js/jquery.js


5.3 通过路径自动跳转到一个页面

  • 这个方法可以实现,一个路径自动跳转到一个页面
  • 相当于使用 new ModelAndView(“login”)方法跳转

在这里插入图片描述

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

//自定义拦截器
@Configuration
public class WebConfigurer implements WebMvcConfigurer {

        @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/goToLogin").setViewName("login");
    }

}    

5.31通过路径自动跳转到一个页面测试

  • 首先是通过ModelAndView方式跳转寻找指定的页面
    在这里插入图片描述
    在这里插入图片描述

  • 通过拦截器addViewControllers方式跳转
    在这里插入图片描述
    在这里插入图片描述


5.4 addCorsMappings(CorsRegistry registry) 设置跨域

  • 主要解决跨域问题(还是建议跨域问题在网关通过配置 CorsWebFilter实例)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

//自定义拦截器
@Configuration
public class WebConfigurer implements WebMvcConfigurer {


    //设置跨域问题 这里最好是在使用网关时配置 CorsWebFilter    CORS
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
        CorsRegistration corsRegistration = registry.addMapping("/**");

        //允许哪些ip或域名可以跨域访问 *表示允许所以,不要写*,否则cookie就无法使用了(这里建议不要用 * ,*表示所以请求都允许跨域,安全部门请喝茶 )
        corsRegistration.allowedOrigins("*");

        //是否发送Cookie信息
        corsRegistration.allowCredentials(true);

        //允许的请求方式
        corsRegistration.allowedMethods("GET", "POST", "DELETE", "PUT");

        //表示访问请求中允许携带哪些Header信息,如:Accept、Accept-Language、Content-Language、Content-Type
        corsRegistration.allowedHeaders("*");

        //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
        corsRegistration.exposedHeaders(HttpHeaders.CONTENT_DISPOSITION);

        //设置等待时间,默认1800秒
        corsRegistration.maxAge(3600);
    }

}   


5.5 addFormatters(FormatterRegistry registry)数据格式化器配置

  • 注入自己定好的日期格式化实例DateFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

//自定义拦截器
@Configuration
public class WebConfigurer implements WebMvcConfigurer {


    @Autowired
    private DateFormatter dateFormatter;

    //通过重写 addFormatters 方法来添加数据格式化器。
    // Spring MVC 接受 HTTP 请求会把参数自动绑定映射到 Controller 请求参数上。
    // Spring 中没有默认配置将字符串转换为日期类型。
    // 这时可以通过添加一个 DateFormatter 类来实现自动转换。
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(dateFormatter);
    }

}   

5.51 首先实现格式化配置实例(这里用日期做实例)

  • 用于接受 HTTP 请求把日期参数自动绑定映射到 Controller 请求参数上
  • Spring 中没有默认配置将字符串转换为日期类型。
  • 这里的日期类型模板是重点,用来表示前台用怎样的形式进行传值。
 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;

@Component
public class DateFormatter implements Formatter<Date> {
	// 日期类型模板:如yyyy-MM-dd
	private String datePattern="yyyy-MM-dd";
	// 日期格式化对象
	private SimpleDateFormat dateFormat;
	// 构造器,通过依赖注入的日期类型创建日期格式化对象
	public DateFormatter(/*String datePattern*/) {
//		this.datePattern=datePattern;
		this.dateFormat = new SimpleDateFormat(datePattern);
	}
 
	// 显示Formatter<T>的T类型对象
	public String print(Date date,Locale locale){
		return dateFormat.format(date);
	}
	
	// 解析文本字符串返回一个Formatter<T>的T类型对象。
	public Date parse(String source, Locale locale) throws ParseException {
		try {
			return dateFormat.parse(source);
		} catch (Exception e) {
			throw new IllegalArgumentException();
		}
		
	}
}

5.52 数据格式化器配置测试

  • 前端传参入口
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;

@RestController
@RequestMapping("/mhh/interceptor")
public class InterceptorTestController {

    @GetMapping("getDate")
    public Date getDate(@RequestParam("date") Date date) {
        return date;
    }
}
  • 这里注意传参的格式要和日期类型模板对应起来

在这里插入图片描述









链接:SpringBoot之WebMvcConfigurer拦截器的常用使用详解 源代码下载地址

标签:拦截器,SpringBoot,自定义,springframework,org,WebMvcConfigurer,import,public
来源: https://blog.csdn.net/JAVA_MHH/article/details/120651297