springboot接口WebMvcConfigurer,自定义拦截器转换器等

WebMvcConfigurer 源码:

public interface WebMvcConfigurer {
	/**
	 *访问路径处理。比如PathMatchConfigurer的setUseTrailingSlashMatch()方法
	 *默认为true,匹配url不考虑结尾的"/",如 “/users”和“/users/”都可以匹配
	 */
    default void configurePathMatch(PathMatchConfigurer configurer) {
    }
	/**
	 *Configure content negotiation options,配置内容协商选项
	 *也就是一个请求路径返回多种数据格式
	 */
    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }
	/**
	 *处理异步请求的。只能设置两个值
	 *一个超时时间(毫秒,Tomcat下默认是10000毫秒,即10秒)
	 *还有一个是AsyncTaskExecutor,异步任务执行器
	 */
    default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    }
	/**
	 *默认静态资源处理器
	 */
    default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    }
	/**
	 *注册自定义转化器
	 */
    default void addFormatters(FormatterRegistry registry) {
    }
	/**
	 *自定义写拦截器
	 */
    default void addInterceptors(InterceptorRegistry registry) {
    }
	/**
	 *自定义资源映射
	 */
    default void addResourceHandlers(ResourceHandlerRegistry registry) {
    }
	/**
	 *设置跨域
	 */
    default void addCorsMappings(CorsRegistry registry) {
    }
	/**
	 *视图跳转控制器
	 */
    default void addViewControllers(ViewControllerRegistry registry) {
    }
	/**
	 *配置视图解析
	 */
    default void configureViewResolvers(ViewResolverRegistry registry) {
    }
	/**
	 *添加自定义方法参数处理器
	 */
    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    }
	/**
	 *添加自定义返回结果处理器
	 */
    default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
    }
	/**
	 *配置消息转换器。重载会覆盖默认注册的HttpMessageConverter
	 */
    default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }
	/**
	 *配置消息转换器。仅添加一个自定义的HttpMessageConverter.
	 */
    default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    }
	/**
	 *配置异常转换器
	 */
    default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }
	/**
	 *添加异常转化器
	 */
    default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    @Nullable
    default Validator getValidator() {
        return null;
    }

    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}

使用方法

  • 使用@EnableWebMvc注解 等于 扩展了WebMvcConfigurationSupport,但是没有重写任何方法
  • 使用“extends WebMvcConfigurationSupport”方式(需要添加@EnableWebMvc),会屏蔽掉springBoot的@EnableAutoConfiguration中的设置
  • 使用“implement WebMvcConfigurer”可以配置自定义的配置,同时也使用了@EnableAutoConfiguration中的设置
  • 使用“implement WebMvcConfigurer + @EnableWebMvc”,会屏蔽掉springBoot的@EnableAutoConfiguration中的设置

这里的“@EnableAutoConfiguration中的设置”是指,读取 application.properties 或 application.yml 文件中的配置

常用方法 implements WebMvcConfigurer接口

跨域 addCorsMappings(CorsRegistry registry)

例子:

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
   	   // 设置允许跨域的路径
        registry.addMapping("/**")
        	// 设置允许跨域请求的域名
            .allowedOrigins("*")
            // 是否允许证书
            .allowCredentials(true)
            // 设置允许的方法
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
             // 设置允许的header属性
             .allowedHeaders("*")
             // 跨域允许时间
            .maxAge(3600);
    }
}

CorsRegistry源码

public class CorsRegistry {

   private final List<CorsRegistration> registrations = new ArrayList<>();

   public CorsRegistration addMapping(String pathPattern) {
      CorsRegistration registration = new CorsRegistration(pathPattern);
      this.registrations.add(registration);
      return registration;
   }
   
   protected Map<String, CorsConfiguration> getCorsConfigurations() {
      Map<String, CorsConfiguration> configs = new LinkedHashMap<>(this.registrations.size());
      for (CorsRegistration registration : this.registrations) {
         configs.put(registration.getPathPattern(), registration.getCorsConfiguration());
      }
      return configs;
   }

} 

CorsRegistry 有个属性registrations ,可以根据不同的项目路径进行定制访问行为

getCorsConfigurations(),这个方法是获取所有CorsConfiguration的Map集合,key值为传入路径pathPattern

egistry对象addMapping()增加完传入路径pathPattern之后,return了一个CorsRegistration对象,是进行更多的配置
CorsRegistration源码

public class CorsRegistration {
    //允许跨域的路径
   private final String pathPattern;
    //配置信息实体类
   private final CorsConfiguration config;
    //构造方法
   public CorsRegistration(String pathPattern) {
      this.pathPattern = pathPattern;
      // Same implicit default values as the @CrossOrigin annotation + allows simple methods
      //与@CrossOrigin注释+相同的隐式默认值允许使用简单方法
      //@CrossOrigin注解可以作用于方法或者类上,实现局部跨域
      this.config = new CorsConfiguration().applyPermitDefaultValues();
   }
    //允许哪些源网站访问,默认所有
   public CorsRegistration allowedOrigins(String... origins) {
      this.config.setAllowedOrigins(Arrays.asList(origins));
      return this;
   }
    //允许何种方式访问,默认简单方式,即:GET,HEAD,POST
   public CorsRegistration allowedMethods(String... methods) {
      this.config.setAllowedMethods(Arrays.asList(methods));
      return this;
   }
    //设置访问header,默认所有
   public CorsRegistration allowedHeaders(String... headers) {
      this.config.setAllowedHeaders(Arrays.asList(headers));
      return this;
   }
    //设置response headers,默认没有(什么都不设置)
   public CorsRegistration exposedHeaders(String... headers) {
      this.config.setExposedHeaders(Arrays.asList(headers));
      return this;
   }
    //是否浏览器应该发送credentials,例如cookies Access-Control-Allow-Credentials
   public CorsRegistration allowCredentials(boolean allowCredentials) {
      this.config.setAllowCredentials(allowCredentials);
      return this;
   }
    //设置等待时间,默认1800秒
   public CorsRegistration maxAge(long maxAge) {
      this.config.setMaxAge(maxAge);
      return this;
   }

   protected String getPathPattern() {
      return this.pathPattern;
   }

   protected CorsConfiguration getCorsConfiguration() {
      return this.config;
   }

}
自定义拦截器addInterceptors(InterceptorRegistry registry)
@Configuration
public class WebConfigurer
        implements WebMvcConfigurer
{
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(LoginInterceptor())
        		.addPathPatterns("/**")
        		.excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**");
    }

	/**
	 *继承了HandlerInterceptor的拦截器
	 */
    @Bean
    public LoginInterceptor LoginInterceptor() {
        return new LoginInterceptor();
    }
}
public interface HandlerInterceptor {
	/**
	*目标方法执行前
	*/
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
	/**
	*目标方法执行后
	*/
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }
	/**
	*页面渲染后
	*/
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
  • addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
  • addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
  • excludePathPatterns:用于设置不需要拦截的过滤规则
视图跳转控制器addViewControllers(ViewControllerRegistry registry)
/**
 *如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面
 *在这里配置之后就不需要了
 *直接访问http://localhost:8080/toLogin 可以直接访问 login.html
 */
@Override
public void addViewControllers(ViewControllerRegistry registry) {
   registry.addViewController("/toLogin").setViewName("login");
}

重写addViewControllers,并不会覆盖WebMvcAutoConfiguration中的addViewControllers(在此方法中,Spring Boot将“/”映射至index.html) 这也就意味着我们自己的配置和Spring Boot的自动配置同时有效
在这里插入图片描述

自定义静态资源映射目录addResourceHandlers(ResourceHandlerRegistry registry)
/**
 * 配置静态访问资源
 * @param registry
 */
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/public-resources/");
}

  • addResoureHandler:指的是对外暴露的访问路径
  • addResourceLocations:指的是内部文件放置的目录

访问自定义public-resources文件夹中的test.jpg 图片的地址为
http://localhost:8080/resources/test.jpg

默认静态资源处理器configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
}

springMVC是通过DispatcherServlet将请求的URL映射到对应的控制器方法上,传统的配置DispatcherServlet的方式是配置在web.xml文件中

但是在servlet3.0的环境中,servlet容器会在类路径中查找javax.servlet.ServletContainerInitializer接口的类,如果能发现,就会用来配置servlet容器。

视图解析器configureViewResolvers(ViewResolverRegistry registry)
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
    registry.jsp("/WEB-INF/view/", ".jsp");
}
configureContentNegotiation(ContentNegotiationConfigurer configurer)
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	 // 是否通过请求Url的扩展名来决定media type 
	 configurer.favorPathExtension(true)
				 // 不检查Accept请求头 
				 .ignoreAcceptHeader(true)
				 // 设置查询参数名,当favorParameter(true)时使用。
				 .parameterName("mediaType")
				 //设置要使用的默认内容类型, 默认情况下不设置此选项
				 .defaultContentType(MediaType.TEXT_HTML)
				 // 请求以.html结尾的会被当成MediaType.TEXT_HTML
				 .mediaType("html", MediaType.TEXT_HTML)
				 // 请求以.json结尾的会被当成MediaType.APPLICATION_JSON
				 .mediaType("json", MediaType.APPLICATION_JSON);
 }
HandlerInterceptorAdapter拦截器

有三个方法

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {    
        return true;    
}    
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {    
}    
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {    
} 
  • preHandle在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理;
    返回true将继续执行,如果返回false,将不进行执行。一般用于登录校验。

  • postHandle在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView;

  • afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面),可以根据ex是否为null判断是否发生了异常,进行日志记录;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值