背景

  1. 问题1:项目中使用默认自带的jackson进行前后端交互,实现数据对象的序列化和反序列化,默认的ObjectMapper采用小驼峰的格式,但是调用其他业务的http接口时,ObjectMapper需要使用蛇形的格式,因此就需要自定义ObjectMapper,然后封装RestTemplate。
  2. 问题2:前后端交互时,JSR310日期序列化时,格式错误;使用springboot自带的jackson,是不支持JSR310的日期,需要全局配置

注意点

  1. 自定义的ObjectMapper不能被IOC管理,因为Springboot默认的ObjectMapper生成条件是:只有当该实例不存在的时候才会创建!
  2. 自定义时,需要支持JSR310的日期,否则序列化LocalDateTime、LocalDate、LocalTime时,就会返回错误的格式。

自定义ObjectMapper

@Slf4j
public class JsonFormatUtils {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
public static final ObjectMapper objectMapper = new ObjectMapper(); static {
//取消时间的转化格式,默认是时间戳,同时需要设置要表现的时间格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
JavaTimeModule javaTimeModule = new JavaTimeModule(); // 默认序列化没有实现,反序列化有实现
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER));
objectMapper.registerModule(javaTimeModule);
// 设置时区
objectMapper.setTimeZone(TimeZone.getDefault());
// 设置格式化输出
// objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// 设置蛇形格式
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
} public static String writeValueAsString(Object obj) {
String result = null;
try {
result = objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.error("objectMapper writeValueAsString exception, e:", e);
}
return result;
} public static <T> T readValue(String str, Class<T> tClass) {
T t = null;
try {
t = objectMapper.readValue(str, tClass);
} catch (JsonProcessingException e) {
log.error("objectMapper readValue exception, e:", e);
}
return t;
}
}

封装RestTemplate

@Configuration
public class RestTemplateConfig {
@Bean("otherRestTemplate")
public RestTemplate algoRestTemplate() {
// 使用apache的httpComponents,封装restTemplate
ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient());
RestTemplate restTemplate = new RestTemplate(factory);
// 使用自定义的ObjectMapper
ObjectMapper objectMapper = JsonFormatUtils.objectMapper;
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
messageConverter.setPrettyPrint(false);
messageConverter.setObjectMapper(objectMapper); List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
messageConverters.removeIf(item -> item.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName()));
messageConverters.add(messageConverter);
return restTemplate;
} private HttpClient httpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(50);
connectionManager.setDefaultMaxPerRoute(10);
connectionManager.setValidateAfterInactivity(2000);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(10000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(1000)
.build();
return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();
}
}

全局配置

底层默认是通过Jackson2ObjectMapperBuilderCustomizer创建的ObjectMapper

@Configuration
public class LocalDateTimeSerializerConfig { private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); @Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Map<Class<?>, JsonSerializer<?>> serializers = new HashMap<>();
serializers.put(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
serializers.put(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER));
serializers.put(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER)); Map<Class<?>, JsonDeserializer<?>> deserializers = new HashMap<>();
deserializers.put(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER));
deserializers.put(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER));
deserializers.put(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
return builder -> builder.serializersByType(serializers).deserializersByType(deserializers);
}
}

springboot自定义ObjectMapper序列化、配置序列化对LocalDateTime的支持的更多相关文章

  1. SpringBoot自定义序列化的使用方式--WebMvcConfigurationSupport

    场景及需求: 项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串. 例如: [     {         "id": 1,      ...

  2. 【转】SpringBoot自定义序列化的使用方式--WebMvcConfigurationSupport

    场景及需求: 项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串. 例如:[     {         "id": 1,       ...

  3. Spring Boot 结合 Redis 序列化配置的一些问题

    前言 最近在学习Spring Boot结合Redis时看了一些网上的教程,发现这些教程要么比较老,要么不知道从哪抄得,运行起来有问题.这里分享一下我最新学到的写法 默认情况下,Spring 为我们提供 ...

  4. 【SpringBoot】 中时间类型 序列化、反序列化、格式处理

    [SpringBoot] 中时间类型 序列化.反序列化.格式处理 Date yml全局配置 spring: jackson: time-zone: GMT+8 date-format: yyyy-MM ...

  5. 如何使用Externalizable接口自定义Java中的序列化

    Java序列化过程的缺点 我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject 和readObject方法自定义序列化过程. 但是这些自定义还不够 ...

  6. Springboot中以配置类方式自定义Mybatis的配置规则(如开启驼峰映射等)

    什么是自定义Mybatis的配置规则? 答:即原来在mybatis配置文件中中我们配置到<settings>标签中的内容,如下第6-10行内容: 1 <?xml version=&q ...

  7. Java之SpringBoot自定义配置与整合Druid

    Java之SpringBoot自定义配置与整合Druid SpringBoot配置文件 优先级 前面SpringBoot基础有提到,关于SpringBoot配置文件可以是properties或者是ya ...

  8. SpringBoot扩展SpringMVC自动配置

    SpringBoot中自动配置了 ViewResolver(视图解析器) ContentNegotiatingViewResolver(组合所有的视图解析器) 自动配置了静态资源文件夹.静态首页.fa ...

  9. SpringBoot + Redis:基本配置及使用

    注:本篇博客SpringBoot版本为2.1.5.RELEASE,SpringBoot1.0版本有些配置不适用 一.SpringBoot 配置Redis 1.1 pom 引入spring-boot-s ...

随机推荐

  1. hive学习笔记之三:内部表和外部表

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. 14 Nginx访问日志自动按天切割

    #!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin LOG_DIR=/usr/loc ...

  3. AcWing 239. 奇偶游戏

    小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...

  4. css图片显示文字(上浮)

    <html> <head lang="en"> <meta charset="UTF-8"> <title>&l ...

  5. PHP Kafka 消息队列使用

      转载自:https://learnku.com/articles/44442 1. 安装 Kafka 服务# 直接到 kafka 官网 , 下载最新的 wget https://mirror.bi ...

  6. buu [MRCTF2020]EasyCpp

    上次没写出,这次认真分析了一下,发现自己的调试水平也有了上涨,也看了一些C++逆向的文章,尤其是stl,发现C++的oop还是挺复杂,这题还没考啥虚函数的还行了. 一.拖入ida,找到主函数,还是挺容 ...

  7. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

  8. 简单聊一下Uwsgi和Django的爱恨情仇

    项目目录:/root/app Uwsgi的配置文件 [uwsgi] # Python扩展包安装的地方 pythonpath=/usr/local/src/python3/lib/python3.5/s ...

  9. SHELL 变量引用

    shell变量的引用非常重要,运用技巧灵活多变 变量的引用主要包含四类:双引号引用.单引号引用.反引号引用.反斜线引用 " " 双引号 屏蔽除美元符号$.反引号( ` )和反斜线( ...

  10. python sqlite3 类

    import sys import os import sqlite3 ##sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/ ...