使用WebMvcConfigurer配置SpringMVC

07-19 1502阅读

一、前言

WebMvcConfigurer配置类是使用Java代码代替传统的xml配置文件,对SpirngMvc进行配置的一种方式,需要创建一个配置类@Configuration并实现WebMvcConfigurer 接口(推荐)。

二、使用方式

官方推荐使用实现WebMvcConfigurer接口(推荐)或者继承WebMvcConfigurationSupport类来实现代码配置。

1.配置类实现WebMvcConfigurer接口

@Configuration
public class WebMvcConfg implements WebMvcConfigurer {}

2.配置类继承WebMvcConfigurationSupport

@Configuration
public class WebMvcConfg extends WebMvcConfigurationSupport {}

三、WebMvcConfigurer接口常用方法

addInterceptors:拦截器
  • addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例

  • addPathPatterns:用于设置拦截器的过滤路径规则;- addPathPatterns(“/**”)对所有请求都拦截

  • excludePathPatterns:用于设置不需要拦截的过滤规则

  • 拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。

    addCorsMappings:跨域
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")  //浏览器允许所有的域访问 / 注意 * 不能满足带有cookie的访问,Origin 必须是全匹配
                    .allowCredentials(true)   // 允许带cookie访问
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                     .allowedHeaders("token")
                    .maxAge(3600);
        }
    
    configureContentNegotiation:默认内容协商配置

    内容协商:在 HTTP 协议中,内容协商是这样一种机制,通过为同一 URI 指向的资源提供不同的展现形式,可以使用户代理选择与用户需求相适应的最佳匹配

      @Override
      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        // 是否通过请求Url的扩展名来决定media type
        configurer.favorPathExtension(false);
        //不检查Accept请求头    设置默认的media type
    configurer.ignoreAcceptHeader(true).defaultContentType(MediaType.APPLICATION_JSON_UTF8);
      }

    上面代码说白了就是告诉系统什么类型用什么来标识。

    addViewControllers:跳转指定页面

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

        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            // 绑定指定URL访问的view名称,这行的意思是在访问/路径时会自动跳转到index.html;如/login则不受影响
            registry.addViewController("/").setViewName("forward:/index.html");
        }
    resourceViewResolver:视图解析器
    configureMessageConverters:信息转换器

    配置在接收request (请求)和返回response (响应)时的数据转换器,最常用到的就是fastJson的转换,配置如下所示

    该方法会替换所有默认的MessageConverters,使用自定义添加converters,在实际项目中应用比例也比较小;

         /**
     * 消息内容转换配置
     */
    @Override
    public void configureMessageConverters(List> converters) {
            converters.add(customerMappingJackson2HttpMessageConverter());
        }
        @Bean
        public MappingJackson2HttpMessageConverter customerMappingJackson2HttpMessageConverter(){
            MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
            //设置日期格式
            ObjectMapper objectMapper = messageConverter.getObjectMapper();
            SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd");
            objectMapper.setDateFormat(smt);
            messageConverter.setObjectMapper(objectMapper);
            //设置中文编码格式
            List list = new ArrayList();
            list.add(MediaType.APPLICATION_JSON);
            messageConverter.setSupportedMediaTypes(list);
            return messageConverter;
        }

    应用场景

    空值处理

    • 请求和返回的数据有很多空值,这些值有时候并没有实际意义,我们可以过滤掉和不返回,或设置成默认值。比如通过重写getObjectMapper方法,将返回结果的空值不进行序列化:
          @Override
          public void extendMessageConverters(List> converters) {
              MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
              ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
              SimpleModule simpleModule = new SimpleModule();
              //Long类型序列化成字符串,避免Long精度丢失
              simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
      //        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
              // XSS序列化
              if (enableXss) {
                  simpleModule.addDeserializer(String.class, new XssJacksonDeserializer());
              }
              // Date
              simpleModule.addSerializer(Date.class, new JacksonDateSerializer());
              simpleModule.addDeserializer(Date.class, new JacksonDateDeserializer());
              simpleModule.addSerializer(LocalDateTime.class, new JacksonLocalDateTimeSerializer());
              simpleModule.addDeserializer(LocalDateTime.class, new JacksonLocalDateTimeDeserializer());
              objectMapper.registerModule(simpleModule)
                      .registerModule(new JavaTimeModule())
                      .registerModule(new ParameterNamesModule())
                      .registerModule(new Jdk8Module());
              jackson2HttpMessageConverter.setObjectMapper(objectMapper);
              //放到第一个
              converters.add(0, jackson2HttpMessageConverter);
          }
      }
      addResourceHandlers:静态资源
      • addResoureHandler:请求静态资源的路径

      • addResourceLocations:静态资源存放位置,可以配置多个,按先后顺序查找

          @Override
          public void addResourceHandlers(ResourceHandlerRegistry registry) {
            // 10 days
            addCacheControl(registry, "img", 864000);
            addCacheControl(registry, "vendor", 864000);
            // 1 day
            addCacheControl(registry, "scripts", 86400);
            addCacheControl(registry, "styles", 86400);
            addCacheControl(registry, "views", 86400);
          }
          private void addCacheControl(ResourceHandlerRegistry registry, String folder, int cachePeriod) {
            registry.addResourceHandler(String.format("/%s/**", folder))
                .addResourceLocations(String.format("classpath:/static/%s/", folder))
                .setCachePeriod(cachePeriod);
          }

        可以对静态资源做缓存控制之类的。

        HttpMessageConverter接口

        • Http请求响应报文其实都是字符串,当请求报文到java程序会被封装为一个ServletInputStream流,供开发人员读取请求报文,响应报文则通过ServletOutputStream流,来输出响应报文。

          从流中只能读取到原始的字符串报文,同样输出流也是。

        • 那么在报文SpringMVC 输入和输出都存在一个字符串到java对象的转化问题。这一过程,在SpringMVC是通过HttpMessageConverter来解决的。
        • 在SpringMVC的处理过程中,一次请求报文和一次响应报文,分别被抽象为一个请求消息HttpInputMessage和一个响应消息HttpOutputMessage。处理请求时,由合适的消息转换器将请求报文绑定为方法中的形参对象,在这里同一个对象就有可能出现多种不同的消息形式,如json、xml。同样响应请求也是同样道理。

          使用WebMvcConfigurer配置SpringMVC

          (1)HttpInputMessage 将请求的信息先转为 InputStream 对象,InputStream 再由 HttpMessageConverter 转换为 SpringMVC 需要的java对象;

          (2)SpringMVC 返回一个 java 对象, 并通过 HttpMessageConverter 转为响应信息,接着 HttpOutputMessage 将响应的信息转换为OutputStream,接着给出响应。

          简单说就是 HTTP request (请求)和response (响应)数据的转换器

          通常实现HttpMessageConverter接口的转换器有以下几种:

          • ByteArrayHttpMessageConverter: 负责读取二进制格式的数据和写出二进制格式的数据;
          • StringHttpMessageConverter: 负责读取字符串格式的数据和写出二进制格式的数据;
          • ResourceHttpMessageConverter:负责读取资源文件和写出资源文件数据;
          • FormHttpMessageConverter: 负责读取form提交的数据(能读取的数据格式为 application/x-www-form-urlencoded,不能读取multipart/form-data格式数据);负责写入application/x-www-from-urlencoded和multipart/form-data格式的数据;
          • MappingJacksonHttpMessageConverter: 负责读取和写入json格式的数据;
          • SourceHttpMessageConverter: 负责读取和写入 xml 中javax.xml.transform.Source定义的数据;
          • Jaxb2RootElementHttpMessageConverter: 负责读取和写入xml 标签格式的数据;
          • AtomFeedHttpMessageConverter: 负责读取和写入Atom格式的数据;
          • RssChannelHttpMessageConverter: 负责读取和写入RSS格式的数据

            在SpringMVC / SpringBoot中@ResponseBody这类注解默认使用的是jackson来解析json

            3.HttpMessageConverter请求信息转换器执行流程

            当用户发送请求后,@Requestbody 注解会读取请求body中的数据,默认的请求转换器HttpMessageConverter通过获取请求头Header中的Content-Type来确认请求头的数据格式,从而来为请求数据适配合适的转换器。

            • 例如contentType=applicatin/json,那么转换器会适配MappingJacksonHttpMessageConverter
            • 响应时候的时候同理,@Responsebody注解会启用HttpMessageConverter,通过检测Header中Accept属性来适配的响应的转换器。

              参考:  https://blog.csdn.net/yuliantao/article/details/136517144

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]