( 十六 ) SpringBoot 定制 Spring MVC

( 十六 ) SpringBoot 定制 Spring MVC

 

 

1、简介

     SpringBoot 抛弃了传统 xml 配置文件,通过配置类(标注 @Configuration 的类,相当于一个 xml 配置文件)以 JavaBean 形式进行相关配置。

SpringBoot 对 Spring MVC 的自动配置可以满足我们的大部分需求,但是我们也可以通过自定义配置类(标注 @Configuration 的类)并实现 WebMvcConfigurer 接口来定制 Spring MVC 配置。WebMvcConfigurer 配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。

SpringBoot 1.5 及以前是通过继承 WebMvcConfigurerAdapter 抽象类来定制 Spring MVC 配置的,但在 SpringBoot 2.0 后,WebMvcConfigurerAdapter 抽象类就被弃用了,改为实现 WebMvcConfigurer 接口来定制 Spring Mvc 配置  或者 直接 继承 WebMvcConfigurationSupport 类。推荐使用实现WebMvcConfigurer 接口。

 

2、WebMvcConfigurer 

WebMvcConfigurer 是一个基于 Java  8 的接口,该接口定义了许多与 Spring MVC 相关的方法,其中大部分方法都是 default 类型的,且都是空实现。因此我们只需要定义一个配置类实现 WebMvcConfigurer 接口,并重写相应的方法便可以定制 Spring MVC 的配置。

方法说明
default void configurePathMatch(PathMatchConfigurer configurer) {} HandlerMappings 路径的匹配规则。
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {} 内容协商策略(一个请求路径返回多种数据格式)。
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {} 处理异步请求。
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {} 这个接口可以实现静态文件可以像 Servlet 一样被访问。
default void addFormatters(FormatterRegistry registry) {} 添加格式化器或者转化器。
default void addInterceptors(InterceptorRegistry registry) {} 添加 Spring MVC 生命周期拦截器,对请求进行拦截处理。
default void addResourceHandlers(ResourceHandlerRegistry registry) {} 添加或修改静态资源(例如图片,js,css 等)映射;
Spring Boot 默认设置的静态资源文件夹就是通过重写该方法设置的。
default void addCorsMappings(CorsRegistry registry) {} 处理跨域请求。
default void addViewControllers(ViewControllerRegistry registry) {} 主要用于实现无业务逻辑跳转,例如主页跳转,简单的请求重定向,错误页跳转等
default void configureViewResolvers(ViewResolverRegistry registry) {} 配置视图解析器,将 Controller 返回的字符串(视图名称),转换为具体的视图进行渲染。
default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {} 添加解析器以支持自定义控制器方法参数类型,实现该方法不会覆盖用于解析处理程序方法参数的内置支持;
要自定义内置的参数解析支持, 同样可以通过 RequestMappingHandlerAdapter 直接配置 RequestMappingHandlerAdapter 。
default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {} 添加处理程序来支持自定义控制器方法返回值类型。使用此选项不会覆盖处理返回值的内置支持;
要自定义处理返回值的内置支持,请直接配置 RequestMappingHandlerAdapter。
default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {} 用于配置默认的消息转换器(转换 HTTP 请求和响应)。
default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {} 直接添加消息转换器,会关闭默认的消息转换器列表;
实现该方法即可在不关闭默认转换器的起提下,新增一个自定义转换器。
default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {} 配置异常解析器。
default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {} 扩展或修改默认的异常解析器列表。


在 Spring Boot 项目中,我们可以通过以下 2 中形式定制 Spring MVC:

  • 扩展 Spring MVC
  • (@EnableWebMvc)全面接管 Spring MVC

示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
//实现 WebMvcConfigurer 接口可以来扩展 SpringMVC 的功能
//@EnableWebMvc   不要完全接管SpringMVC
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //当访问 “/” 或 “/index.html” 时,都直接跳转到登陆页面
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
    }
}

 启动 Spring Boot,您会发现“http://localhost:8080/login”、“http://localhost:8080/”“http://localhost:8080/index.html”3 个 URL 都能跳转到登陆页 login.html

注意: 当我们全面接管 Spring MVC 后,Spring Boot 对 Spring MVC 的默认配置都会失效。所以非必要条件下请不要使用 @EnableWebMvc

 

 

3、常用的方法:

3.1、addInterceptors:拦截器

  • addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
  • addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截
  • excludePathPatterns:用于设置不需要拦截的过滤规则
  • 拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
@Override
public void addInterceptors(InterceptorRegistry registry) {
    super.addInterceptors(registry);
    registry.addInterceptor(new TestInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**"); }

 

3.2、 addViewControllers:页面跳转

以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurer中的addViewControllers方法即可达到效果了

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

 

3.3、 addResourceHandlers:静态资源

比如,我们想自定义静态资源映射目录的话,只需重写addResourceHandlers方法即可

@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
    /**
     * 配置静态访问资源
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/");
    }
}
  • addResoureHandler:指的是对外暴露的访问路径
  • addResourceLocations:指的是内部文件放置的目录

 

3.4、 configureDefaultServletHandling:默认静态资源处理器

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
        configurer.enable("defaultServletName");
}

 

3.5、 configureViewResolvers:视图解析器

这个方法是用来配置视图解析器的,该方法的参数ViewResolverRegistry 是一个注册器,用来注册你想自定义的视图解析器等

/**
 * 配置请求视图映射
 * @return
 */
@Bean
public InternalResourceViewResolver resourceViewResolver()
{
    InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
    //请求视图文件的前缀地址
    internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
    //请求视图文件的后缀
    internalResourceViewResolver.setSuffix(".jsp");
    return internalResourceViewResolver;
}
 
/**
 * 视图配置
 * @param registry
 */
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
    super.configureViewResolvers(registry);
    registry.viewResolver(resourceViewResolver());
    /*registry.jsp("/WEB-INF/jsp/",".jsp");*/

 

3.7、 addCorsMappings:跨域

@Override
public void addCorsMappings(CorsRegistry registry) {
    super.addCorsMappings(registry);
    registry.addMapping("/cors/**")
            .allowedHeaders("*")
            .allowedMethods("POST","GET")
            .allowedOrigins("*");
}

 

3.8、 configureMessageConverters:信息转换器

/**
* 消息内容转换配置
 * 配置fastJson返回json转换
 * @param converters
 */
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    //调用父类的配置
    super.configureMessageConverters(converters);
    //创建fastJson消息转换器
    FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
    //创建配置类
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    //修改配置返回内容的过滤
    fastJsonConfig.setSerializerFeatures(
            SerializerFeature.DisableCircularReferenceDetect,
            SerializerFeature.WriteMapNullValue,
            SerializerFeature.WriteNullStringAsEmpty
    );
    fastConverter.setFastJsonConfig(fastJsonConfig);
    //将fastjson添加到视图消息转换器列表内
    converters.add(fastConverter);
 
}

 

posted @ 2019-06-16 18:41  邓维-java  阅读(8504)  评论(0编辑  收藏  举报