springboot2.x中jackson中objectMapper相关

springboot2.x中springmvc对于http消息进行序列化和反序列化的核心是HttpMessageConverter(消息转换器),对于JSON格式数据转换,Spring默认采用MappingJackson2HttpMessageConverter,Springboot会将MappingJackson2HttpMessageConverter自动装载到IOC容器中。

@Configuration(proxyBeanMethods = false)
class JacksonHttpMessageConvertersConfiguration {

   @Configuration(proxyBeanMethods = false)
   @ConditionalOnClass(ObjectMapper.class)
   @ConditionalOnBean(ObjectMapper.class)
   @ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY,
         havingValue = "jackson", matchIfMissing = true)
   static class MappingJackson2HttpMessageConverterConfiguration {

      @Bean
      @ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class,
            ignoredType = {
                  "org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter",
                  "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })
      MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
         return new MappingJackson2HttpMessageConverter(objectMapper);
      }

   }

      .......

}

其中ObjectMapper是Spring容器中的bean,当没有自定义配置ObjectMapper时,会自动注入IOC容器。当需要自定义序列化/反序列化的配置时,就需要对ObjectMapper进行配置。

@Configuration(proxyBeanMethods = false)
// 当引入了Jackson的包,可以找到ObjectMapper.class这个类,才会构建Bean
@ConditionalOnClass(ObjectMapper.class)
public class JacksonAutoConfiguration {

   private static final Map<?, Boolean> FEATURE_DEFAULTS;

   static {
      Map<Object, Boolean> featureDefaults = new HashMap<>();
      // Date类型默认默认不会转换为时间戳类型
      featureDefaults.put(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
      FEATURE_DEFAULTS = Collections.unmodifiableMap(featureDefaults);
   }

   @Bean
   public JsonComponentModule jsonComponentModule() {
      return new JsonComponentModule();
   }

   @Configuration(proxyBeanMethods = false)
   @ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
   static class JacksonObjectMapperConfiguration {

      @Bean
      @Primary
      // 当容器中不存在ObjectMapper 这个Bean,才会生成默认Bean,故当自定义了ObjectMapper到容器中,默认配置不会生效
      @ConditionalOnMissingBean
      ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
         return builder.createXmlMapper(false).build();
      }

   }

......

}

我们使用的@RequestBody和@ResponseBoby注解,作用就是将报文反序列化/序列化POJO对象

在请求时SpringMVC会在请求头中寻找contentType参数,然后去匹配能够处理这种类型的消息转换器。而在返回数据时,SpringMVC根据请求头的Accept属性,再将对象转换成响应报文。

SpringBoot2.x自动装载MappingJackson2HttpMessageConvereter消息转换器,MappingJacson2HttpMessageConverter会获取容器中ObjectMapper的配置,来进行Jackson的序列化和反序列化。ObjectMapper时JSON操作的核心,Jackson的JSON操作都是通过ObjectMapper实现的。

注:SpringBoot2.x中不要将自定义的PObjectMapper对象放入Spring容器中,否则会导致默认的ObejctMapper配置被覆盖掉。

SpringBoot2.x可以通过yaml文件只用sprig.jackson为前缀的配置修改ObjectMapper,也可以通过Jackson2ObjectMapperBuilderCustomizer接口代码修改ObjectMapper配置。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperBuilderConfiguration {

   @Bean
   @Scope("prototype")
   @ConditionalOnMissingBean
   Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(ApplicationContext applicationContext,
         List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
      Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
      builder.applicationContext(applicationContext);
      customize(builder, customizers);
      return builder;
   }

   private void customize(Jackson2ObjectMapperBuilder builder,
         List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
      for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
         customizer.customize(builder);
      }
   }

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
@EnableConfigurationProperties(JacksonProperties.class)
static class Jackson2ObjectMapperBuilderCustomizerConfiguration {

   @Bean
   StandardJackson2ObjectMapperBuilderCustomizer standardJacksonObjectMapperBuilderCustomizer(
         ApplicationContext applicationContext, JacksonProperties jacksonProperties) {
      return new StandardJackson2ObjectMapperBuilderCustomizer(applicationContext, jacksonProperties);
   }

   static final class StandardJackson2ObjectMapperBuilderCustomizer
         implements Jackson2ObjectMapperBuilderCustomizer, Ordered {

      private final ApplicationContext applicationContext;

      private final JacksonProperties jacksonProperties;

      StandardJackson2ObjectMapperBuilderCustomizer(ApplicationContext applicationContext,
            JacksonProperties jacksonProperties) {
         this.applicationContext = applicationContext;
         this.jacksonProperties = jacksonProperties;
      }

      @Override
      public int getOrder() {
         return 0;
      }

      @Override
      public void customize(Jackson2ObjectMapperBuilder builder) {

         if (this.jacksonProperties.getDefaultPropertyInclusion() != null) {
            builder.serializationInclusion(this.jacksonProperties.getDefaultPropertyInclusion());
         }
         if (this.jacksonProperties.getTimeZone() != null) {
            builder.timeZone(this.jacksonProperties.getTimeZone());
         }
         configureFeatures(builder, FEATURE_DEFAULTS);
         configureVisibility(builder, this.jacksonProperties.getVisibility());
         configureFeatures(builder, this.jacksonProperties.getDeserialization());
         configureFeatures(builder, this.jacksonProperties.getSerialization());
         configureFeatures(builder, this.jacksonProperties.getMapper());
         configureFeatures(builder, this.jacksonProperties.getParser());
         configureFeatures(builder, this.jacksonProperties.getGenerator());
         configureDateFormat(builder);
         configurePropertyNamingStrategy(builder);
         configureModules(builder);
         configureLocale(builder);
      }

        ......

        }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值