轻量级前端框架助力开发者提升项目效率与性能
1849
2022-11-18
Springboot2以代码的方式统一配置Jackson教程
目录说明7个序列化和反序列化规则Jackson统一配置类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
@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 @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 @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 @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 @Override public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { long timestamp = p.getValueAsLong(); if (timestgqfieTTYgamp > 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 @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 @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 try { return objectMapper.readValue(json, clazz); } catch (IOException e) { throw new RuntimeException("解析json错误"); } } @SuppressWarnings("unchecked") public static try { return (T)objectMapper.readValue(json, tr); } catch (IOException e) { throw new RuntimeException("解析json错误", e); } } /** * obj 转换成json * * @param entity * @return */ public static 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 * @param json * @param valueType * @return T */ @SuppressWarnings("unchecked") public static 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); } } } 总结
@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
@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
@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
@Override
public Date deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
long timestamp = p.getValueAsLong();
if (timestgqfieTTYgamp > 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
@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
@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
try {
return objectMapper.readValue(json, clazz);
} catch (IOException e) {
throw new RuntimeException("解析json错误");
}
}
@SuppressWarnings("unchecked")
public static
try {
return (T)objectMapper.readValue(json, tr);
} catch (IOException e) {
throw new RuntimeException("解析json错误", e);
}
}
/**
* obj 转换成json
*
* @param entity
* @return
*/
public static
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
* @param json
* @param valueType
* @return T
*/
@SuppressWarnings("unchecked")
public static
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);
}
}
}
总结
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~