springboot自定义ObjectMapper序列化、配置序列化对LocalDateTime的支持
背景
- 问题1:项目中使用默认自带的jackson进行前后端交互,实现数据对象的序列化和反序列化,默认的ObjectMapper采用小驼峰的格式,但是调用其他业务的http接口时,ObjectMapper需要使用蛇形的格式,因此就需要自定义ObjectMapper,然后封装RestTemplate。
- 问题2:前后端交互时,JSR310日期序列化时,格式错误;使用springboot自带的jackson,是不支持JSR310的日期,需要全局配置
注意点
- 自定义的ObjectMapper不能被IOC管理,因为Springboot默认的ObjectMapper生成条件是:只有当该实例不存在的时候才会创建!
- 自定义时,需要支持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的支持的更多相关文章
- SpringBoot自定义序列化的使用方式--WebMvcConfigurationSupport
场景及需求: 项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串. 例如: [ { "id": 1, ...
- 【转】SpringBoot自定义序列化的使用方式--WebMvcConfigurationSupport
场景及需求: 项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串. 例如:[ { "id": 1, ...
- Spring Boot 结合 Redis 序列化配置的一些问题
前言 最近在学习Spring Boot结合Redis时看了一些网上的教程,发现这些教程要么比较老,要么不知道从哪抄得,运行起来有问题.这里分享一下我最新学到的写法 默认情况下,Spring 为我们提供 ...
- 【SpringBoot】 中时间类型 序列化、反序列化、格式处理
[SpringBoot] 中时间类型 序列化.反序列化.格式处理 Date yml全局配置 spring: jackson: time-zone: GMT+8 date-format: yyyy-MM ...
- 如何使用Externalizable接口自定义Java中的序列化
Java序列化过程的缺点 我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject 和readObject方法自定义序列化过程. 但是这些自定义还不够 ...
- Springboot中以配置类方式自定义Mybatis的配置规则(如开启驼峰映射等)
什么是自定义Mybatis的配置规则? 答:即原来在mybatis配置文件中中我们配置到<settings>标签中的内容,如下第6-10行内容: 1 <?xml version=&q ...
- Java之SpringBoot自定义配置与整合Druid
Java之SpringBoot自定义配置与整合Druid SpringBoot配置文件 优先级 前面SpringBoot基础有提到,关于SpringBoot配置文件可以是properties或者是ya ...
- SpringBoot扩展SpringMVC自动配置
SpringBoot中自动配置了 ViewResolver(视图解析器) ContentNegotiatingViewResolver(组合所有的视图解析器) 自动配置了静态资源文件夹.静态首页.fa ...
- SpringBoot + Redis:基本配置及使用
注:本篇博客SpringBoot版本为2.1.5.RELEASE,SpringBoot1.0版本有些配置不适用 一.SpringBoot 配置Redis 1.1 pom 引入spring-boot-s ...
随机推荐
- Linux中mail的用法
简介:mail命令是命令行的电子邮件发送和接收工具.操作的界面不像elm或pine那么容易使用,但功能非常完整Red Hat上sendmail服务一般是自动启动的.可以通过下面的命令查看sendmai ...
- Zabbix5.0钉钉报警(centos7)
2.1.到钉钉官网下载pc版钉钉,安装.注册.登陆: 钉钉下载地址:https://www.dingtalk.com/ 2.2.创建群聊和钉钉机器人: 1.创建群聊,把需要收到报警的人员都拉到这个群: ...
- 16、编译安装ansible
16.1.python版本说明: Ansible是一种批量部署工具,现在运维人员用的最多的三种开源集中化管理工具有:puppet,saltstack,ansible,各有各的优缺点, 其中saltst ...
- ACM金牌选手整理的【LeetCode刷题顺序】
算法和数据结构知识点图 首先,了解算法和数据结构有哪些知识点,在后面的学习中有 大局观,对学习和刷题十分有帮助. 下面是我花了一天时间花的算法和数据结构的知识结构,大家可以看看. 后面是为大家 精心挑 ...
- hadoop安装前的准备
1.操作系统安装 2.hostname设定 3.hosts文件设定 4.ssh免密码登录 5.NTP时间同步设定 6.iptables永久关闭 7.selinux永久关闭
- Mybatis学习(1)开发环境搭建
什么是mybatis MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML ...
- buu crypto 变异凯撒
一.由题目就可知是凯撒加密,但是是变异,说明有改动,但是凯撒的本质移位是不变的,将密文afZ_r9VYfScOeO_UL^RWUc,和flag进行比较,字符表查一下,发现 a:97 f:102 f:1 ...
- Flask(9)- 蓝图的基本使用
前言 在前面的例子中,所有的页面处理逻辑都是放在同一个文件中,随着业务代码的增加,将所有代码都放在单个程序文件中是非常不合适的 不仅会让阅读代码变得困难,而且会给后期维护带来麻烦 Flask 中使用蓝 ...
- 备战-Java 容器
备战-Java 容器 玉阶生白露,夜久侵罗袜. 简介:备战-Java 容器 一.概述 容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着k ...
- VMware中的虚机如何挂载U盘
1.将U盘插入到宿主机上. 2.在VM Client上,点击宿主机,右键,扫描存储设备(目的是为了发现新USB存储) 3.在需要的虚拟机上编辑配置,添加硬件,添加USB设备(如果不进行以上2个步骤,此 ...