文章目录
WebMvcConfigurerAdapter
WebMvcConfigurerAdapter作用
Spring内部的一种配置方式
采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制。
WebMvcConfigurerAdapter 的作用是进行SpringMVC的一些配置
在Spring中,为了减少xml的配置,引入了@Configuration注解。
总结: 该方法已弃用, Spring 5.0 以后WebMvcConfigurerAdapter会取消掉.
现用方式
@Configuration
public class WebMvcConfg implements WebMvcConfigurer {
//TODO
}
WebMvcConfigurerAdapter常用的方法
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
/** 添加拦截器 **/
void addInterceptors(InterceptorRegistry registry);
/** 这里配置视图解析器 **/
void configureViewResolvers(ViewResolverRegistry registry);
/** 配置内容裁决的一些选项 **/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 视图跳转控制器 **/
void addViewControllers(ViewControllerRegistry registry);
/** 静态资源处理 **/
void addResourceHandlers(ResourceHandlerRegistry registry);
/** 默认静态资源处理器 **/
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
1、addInterceptors:拦截器
addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
addPathPatterns:用于设置拦截器的过滤路径规则
excludePathPatterns:用于设置不需要拦截的过滤规则
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
}
WebMvcConfigurerAdapter过时的替换方法
WebMvcConfigurerAdapter过时的替换方法
转自:https://blog.csdn.net/tyvbpq/article/details/83588508
Spring 5.0后,WebMvcConfigurerAdapter被废弃,取代的方法有两种:
①implements WebMvcConfigurer(官方推荐)
②extends WebMvcConfigurationSupport
使用第一种方法是实现了一个接口,可以任意实现里面的方法,不会影响到Spring Boot自身的@EnableAutoConfiguration,而使用第二种方法相当于覆盖了@EnableAutoConfiguration里的所有方法,每个方法都需要重写,比如,若不实现方法addResourceHandlers(),则会导致静态资源无法访问,实现的方法如下:
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/public/");
super.addResourceHandlers(registry);
}
所以,采用第一种方法更加简单方便,不容易出现意料之外的bug
总结:
spring5以上版本不建议使用,所以把原来的继承 WebMvcConfigurerAdapter改为
public class CustomWebConigurer implements WebMvcConfigurer
可以实现相同的功能。
是1.8以后接口中可以不必实现接口的抽象方法才变化的。
WebMvcConfigurerAdapter 其实也是实现了 WebMvcConfigurer接口的
使用示例
第一种:
@Configuration
public class WebAppConfig implements WebMvcConfigurer{
@Bean
public HandlerInterceptor getLoginInterceptor(){
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(getLoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/error")
.excludePathPatterns("/static/*");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")//设置允许跨域的路径
.allowedOrigins("*")//设置允许跨域请求的域名
.allowCredentials(true)//是否允许证书 不再默认开启
.allowedMethods("GET", "POST", "PUT", "DELETE")//设置允许的方法
.maxAge(3600);//跨域允许时间
}
}
使用这个在升级springboot2.0之后会把Date类型字段自动给转成UTC字符串 如:1990-11-26T16:00:00.000+0000,如果想转成时间戳在application.properties配置文件增加以下配置:
···
spring.jackson.serialization.write-dates-as-timestamps=true
spring.jackson.time-zone=GMT+8
···
第二种(会导致springboot的自动配置失效):
···
@Configuration
public class WebAppConfig extends WebMvcConfigurationSupport{
...
}
这种方式会把Date类型字段自动给转成时间戳,如果想用UTC字符串,在application.properties配置文件增加以下配置:
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
# HandlerInterceptorAdapter
[推荐]SpringBoot中的HandlerInterceptorAdapter
参考URL: https://blog.csdn.net/zhaoruda/article/details/80206361
**在SpringBoot中我们可以使用HandlerInterceptorAdapter这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。**
在HandlerInterceptorAdapter中主要提供了以下的方法:
* preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法不会被执行,但是你可以修改response为你想要的响应。
* postHandle:在方法执行后调用。
* afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。
Spring Boot 之FilterRegistrationBean-自定义Filter
[推荐]spring boot 配置Filter过滤器方法总结
参考URL: https://blog.csdn.net/testcs_dn/article/details/80265196
在springboot 中,主要是靠FilterRegistrationBean 这个类来提供这样的功能。具体而言:
自定义Filter需要两个步骤:
实现Filter【javax.servlet.Filter】接口,实现Filter方法
添加 @Configuration 注解,将自定义Filter加入过滤链
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean httpFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
//setFilter就是你所定义的过滤器filter类。
// 另外当你有多个拦截器的时候,可以再添加registratrion.setOrder(**)进行设置。
registrationBean.setFilter(new HttpFilter());
registrationBean.addUrlPatterns("/threadLocal/*");
return registrationBean;
}
/**
* 添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/*");
}
}
一、在spring的应用中我们存在两种过滤的用法,一种是拦截器、另外一种当然是过滤器。我们这里介绍过滤器在springboot的用法,在springmvc中的用法基本上一样,只是配置上面有点区别。
二、filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response**,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.**换种说法,filter其实是一个”servlet chaining”(servlet 链).
一个Filter包括:
1)、在servlet被调用之前截获;
2)、在servlet被调用之前检查servlet request;
3)、根据需要修改request头和request数据;
4)、根据需要修改response头和response数据;
5)、在servlet被调用之后截获.
@Component
@ServletComponentScan
@WebFilter(urlPatterns = "/login/*",filterName = "loginFilter")
public class LoginFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
- @Component 这个注解的目的是将LoginFilter交给容器来处理。也就是让LoginFilter起作用
- @WebFilter 这个用处显而易见,针对于什么链接做过滤,filter的名称是为什么。
总结: Filter是Servlet规范规定的,不属于spring框架,也是用于请求的拦截。但是它适合更粗粒度的拦截,在请求前后做一些编解码处理、日志记录等。
spring boot 配置Filter过滤器
1、通过 @WebFilter 注解来配置
@Component
@WebFilter(urlPatterns = "/webapi/*", filterName = "authFilter")
public class AuthFilter implements Filter {
......
}
2、通过 @Bean 注解来配置
我这个是写在带 @SpringBootApplication 注解的类里面的。
@Bean
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new TestFilter());
registration.addUrlPatterns("/webapi/*"); //
registration.addInitParameter("paramName", "paramValue"); //
registration.setName("testFilter");
return registration;
}
那如果有多个过虑器,怎么指定执行的顺序呢?
通过 registration.setOrder(1); 来设置,例如:
@Bean
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new TestFilter());
registration.addUrlPatterns("/webapi/*"); //
registration.addInitParameter("paramName", "paramValue"); //
registration.setName("testFilter");
registration.setOrder(1);
return registration;
}
@Bean
public FilterRegistrationBean authFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new AuthFilter());
registration.addUrlPatterns("/webapi/*"); //
registration.addInitParameter("paramName", "paramValue"); //
registration.setName("authFilter");
registration.setOrder(2);
return registration;
}
注意:
1、如果指定了 Order 属性,执行的顺序与注册的顺序是无关的;
2、数字越小,优先级越高;
关于 @Order 注解
有文章提到使用 @Order 注解来指定顺序,亲测无效。
编码 filter Bean总结
思路1 :
定义一个HttpFilter类,不加@Component的情况,我们可以在 implements WebMvcConfigurer的配置类中使用@Bean返回,HttpFilter类的实例
@WebFilter(filterName = "HttpFilter")
@Slf4j
public class HttpFilter implements Filter {
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean httpFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
//setFilter就是你所定义的过滤器filter类。
// 另外当你有多个拦截器的时候,可以再添加registratrion.setOrder(**)进行设置。
registrationBean.setFilter(new HttpFilter());
registrationBean.addUrlPatterns("/threadLocal/*");
return registrationBean;
}
思路2【推荐】: 完成使用注解,@Component注解实现implements Filter的类,让spring管理即可。
···
@WebFilter(filterName = “HttpFilter”, urlPatterns = “/threadLocal/*”)
@Slf4j
@Component
public class HttpFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
log.info("do filter!{}{}",Thread.currentThread().getId(),((HttpServletRequest) req).getServletPath());
RequestHolder.add(Thread.currentThread().getId());
chain.doFilter(req,resp);
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}
···