软件编程
位置:首页>> 软件编程>> java编程>> Springboot2以代码的方式统一配置Jackson教程

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com