Springboot2以代码的方式统一配置Jackson教程
作者:jingxian 发布时间:2021-08-30 16:47:33
标签:Springboot2,配置,Jackson
说明
本文主要配置Jackson对Long、Date、LocalDate、LocalDateTime的序列化和反序列化。
由于js中整数可精确表示范围小于java Long的范围,故将Long序列化为String,反序列化Jackson会自动处理String转Long,故不需要显式配置。
由于时间戳在各语言间的兼容性良好,故将Date、LocalDate、LocalDateTime序列化为Long(目前时间戳类的Long类型在js的可精确表示范围内),将Long反序列化为Date、LocalDate、LocalDateTime。将String空字符串反序列化为null。
本文除了配置Springboot整合的Jackson,还配置了功能一致的Jackson工具类,方便在代码中显示使用Jackson的序列化和反序列化功能。
7个序列化和反序列化规则
package com.xxx.config.serializers;
import java.io.IOException;
import java.util.Date;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class DateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value != null) {
gen.writeNumber(value.getTime());
}
}
}
package com.xxx.config.serializers;
import java.io.IOException;
import java.time.LocalDate;
import java.time.ZoneId;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class LocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value != null) {
long millis = value.atStartOfDay(ZoneId.of("+8")).toInstant().toEpochMilli();
gen.writeNumber(millis);
}
}
}
package com.xxx.config.serializers;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value != null) {
long millis = value.atZone(ZoneId.of("+8")).toInstant().toEpochMilli();
gen.writeNumber(millis);
}
}
}
package com.xxx.config.serializers;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class StringDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String text = p.getText();
if ("".equals(text)) {
return null;
}
return text;
}
}
package com.xxx.config.serializers;
import java.io.IOException;
import java.util.Date;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class DateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
long timestamp = p.getValueAsLong();
if (timestamp > 0){
return new Date(timestamp);
}else{
return null;
}
}
}
package com.xxx.config.serializers;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
long timestamp = p.getValueAsLong();
if (timestamp > 0){
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp),ZoneId.of("+8")).toLocalDate();
}else{
return null;
}
}
}
package com.xxx.config.serializers;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
long timestamp = p.getValueAsLong();
if (timestamp > 0){
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp),ZoneId.of("+8"));
}else{
return null;
}
}
}
Jackson统一配置类
package com.xxx.config;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.xxx.config.serializers.DateDeserializer;
import com.xxx.config.serializers.DateSerializer;
import com.xxx.config.serializers.LocalDateDeserializer;
import com.xxx.config.serializers.LocalDateSerializer;
import com.xxx.config.serializers.LocalDateTimeDeserializer;
import com.xxx.config.serializers.LocalDateTimeSerializer;
import com.xxx.config.serializers.StringDeserializer;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Jackson2ObjectMapperBuilderCustomizer customizer = new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder
.serializerByType(Long.TYPE, ToStringSerializer.instance)
.serializerByType(Long.class, ToStringSerializer.instance)
.serializerByType(Date.class, new DateSerializer())
.serializerByType(LocalDate.class, new LocalDateSerializer())
.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer())
.deserializerByType(String.class, new StringDeserializer())
.deserializerByType(Date.class, new DateDeserializer())
.deserializerByType(LocalDate.class, new LocalDateDeserializer())
.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer())
.failOnEmptyBeans(false)
.failOnUnknownProperties(false);
}
};
return customizer;
}
}
Jackson工具类
package com.xxx.util;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.TimeZone;
import com.xxx.config.serializers.StringDeserializer;
import com.xxx.config.serializers.DateDeserializer;
import com.xxx.config.serializers.DateSerializer;
import com.xxx.config.serializers.LocalDateDeserializer;
import com.xxx.config.serializers.LocalDateSerializer;
import com.xxx.config.serializers.LocalDateTimeDeserializer;
import com.xxx.config.serializers.LocalDateTimeSerializer;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
public class JsonUtils {
private static final ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
// 去掉默认的时间戳格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// 设置为中国北京时区
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// 空值不序列化
// objectMapper.setSerializationInclusion(Include.NON_NULL);//已过时
// objectMapper.setDefaultPropertyInclusion(Include.NON_NULL);//新API
// 反序列化时,属性不存在的兼容处理
objectMapper.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 单引号处理
objectMapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
javaTimeModule.addSerializer(Long.class, ToStringSerializer.instance);
javaTimeModule.addSerializer(Date.class, new DateSerializer());
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer());
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
javaTimeModule.addDeserializer(String.class, new StringDeserializer());
javaTimeModule.addDeserializer(Date.class, new DateDeserializer());
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
objectMapper.registerModule(javaTimeModule);
}
/**
* json 转换成 Object
*
* @param json
* @param clazz
* @return
*/
public static <T> T json2Object(String json, Class<T> clazz) {
try {
return objectMapper.readValue(json, clazz);
} catch (IOException e) {
throw new RuntimeException("解析json错误");
}
}
@SuppressWarnings("unchecked")
public static <T> T json2Object(String json, TypeReference<T> tr) {
try {
return (T)objectMapper.readValue(json, tr);
} catch (IOException e) {
throw new RuntimeException("解析json错误", e);
}
}
/**
* obj 转换成json
*
* @param entity
* @return
*/
public static <T> String object2Json(T entity) {
try {
return objectMapper.writeValueAsString(entity);
} catch (IOException e) {
throw new RuntimeException("转换json错误");
}
}
/**
* obj对象 转换成树型JSON
*
* @param obj
* @return
*/
public static JsonNode object2TreeJson(Object obj) {
try {
return objectMapper.valueToTree(obj);
} catch (Exception e) {
throw new RuntimeException("转换json错误");
}
}
/**
* 解码json串成对象
*
* @param <T>
* @param json
* @param valueType
* @return T
*/
@SuppressWarnings("unchecked")
public static <T> T decode(String json, Class<?> valueType) {
try {
return (T) objectMapper.readValue(json, valueType);
} catch (Exception e) {
throw new RuntimeException(json, e);
}
}
/**
* 解码json串成JsonNode
* @param json
* @return
*/
public static JsonNode readTree(String json) {
try {
return objectMapper.readTree(json);
} catch (Exception e) {
throw new RuntimeException(json, e);
}
}
}
来源:https://blog.csdn.net/daodfs111/article/details/112446605


猜你喜欢
- 本文实例讲述了Android开发之多媒体文件获取工具类。分享给大家供大家参考,具体如下:package com.android.ocr.ut
- C#编程中,调用封装dll中的函数是高频使用的。那么,如何在程序中加载dll并调用其中的函数呢?更进一步的,如何在主程序中对自己封装的dll
- 前言在电商的应用中,最常见的就是在首页或完成某事件之后,弹出一堆的活动/广告。假如重叠弹出,很丑,给用户的体验也不好,所以一般都会依次依条件
- 本文实例为大家分享了Android倒计时进度条展示的具体代码,供大家参考,具体内容如下效果预览源代码传送门:https://github.c
- 本文实例为大家分享了java实现文件上传下载的具体代码,供大家参考,具体内容如下1.上传单个文件Controller控制层import ja
- 要讲到C#源码的执行过程 首先要提下程序集,因为Clr并不是和托管摸块打交道的,而是和程序集(dll,exe)1、从哪里来程序集是由一个或者
- 题外由于idea原因 用注解test无法在控制台上输入所以写死到程序里了,版本都30.9102了为什么还是这样啊,intelJ你们该反思了!
- ComparableComparable 是排序接口。若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Compa
- 1.前言NameServer主要作用是为消息消费者和消息生产者提供关于主题Topic的路由信息,那么NameServer需要存储路由的基本信
- 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出改进方
- 伤害数字显示HUD游戏中收到伤害掉血,会有飘动的伤害数值;可以使用OnGUI中GUI.Label来实现;可自定义字体,颜色,大小等;如果需要
- using System;using System.Collections.Generic;using System.Data;using
- 目录1.启动分为两种方式2.如何测量一个应用的启动时间3.应用启动的流程4.减少应用的启动时间的耗时5.如何设计延迟加载DelayLoad1
- 引言内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑。不过世界上不存在
- 这里使用的是spring-security和原生的jasig cas包来进行整合,为什么没有直接使用spring提供的spring-secu
- 目录简介匿名方法的参数使用范围委托示例简介在 C# 2.0 之前的版本中,我们创建委托的唯一形式 -- 命名方法。而 C# 2.0 -- 引
- 构造函数、析构函数构造函数:1.若没提供任何构造函数,则系统会自动提供一个默认的构造函数,初始化所有成员为默认值(引用类型为空引用null,
- 参数传递即将参数传输到程序后台中,后台可能做一些处理,然后再将内容存入数据库之类嗒!参数传递的方法较多,一一说明如下。1、Action中直接
- 本文实例讲述了java实现List中对象排序的方法。分享给大家供大家参考,具体如下:package com.test; import jav
- 本文以一个非常简单的实例讲述了Winform实现抓取web页面内容的方法,代码简洁易懂,非常实用!分享给大家供大家参考。具体实现代码如下:W