Springboot2以代码的方式统一配置Jackson教程

网友投稿 473 2022-09-12


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 T json2Object(String json, Class clazz) {

try {

return objectMapper.readValue(json, clazz);

} catch (IOException e) {

throw new RuntimeException("解析json错误");

}

}

@SuppressWarnings("unchecked")

public static T json2Object(String json, TypeReference tr) {

try {

return (T)objectMapper.readValue(json, tr);

} catch (IOException e) {

throw new RuntimeException("解析json错误", e);

}

}

/**

* obj 转换成json

*

* @param entity

* @return

*/

public static 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

* @param json

* @param valueType

* @return T

*/

@SuppressWarnings("unchecked")

public static 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);

}

}

}

总结

@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 T json2Object(String json, Class clazz) {

try {

return objectMapper.readValue(json, clazz);

} catch (IOException e) {

throw new RuntimeException("解析json错误");

}

}

@SuppressWarnings("unchecked")

public static T json2Object(String json, TypeReference tr) {

try {

return (T)objectMapper.readValue(json, tr);

} catch (IOException e) {

throw new RuntimeException("解析json错误", e);

}

}

/**

* obj 转换成json

*

* @param entity

* @return

*/

public static 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

* @param json

* @param valueType

* @return T

*/

@SuppressWarnings("unchecked")

public static 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);

}

}

}

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:时间同步综合测量解决方案(时间同步精度测试)
下一篇:使用flow、debug 工具排查Juniper srx故障(使用筷子会不会传染乙肝病毒)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~