ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-10-23 17:02:17  阅读:302  来源: 互联网

标签:拦截器 SpringBoot 自定义 springframework org WebMvcConfigurer import public


目录

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有