springboot專案中jackson-序列化-處理 NULL教程
在專案中有事需要對值為NULL的物件中Field不做序列化輸入配置方式如下:
[配置型別]:
原始碼包中的列舉類:
public static enum Include { ALWAYS,NON_NULL,NON_ABSENT,NON_EMPTY,NON_DEFAULT,USE_DEFAULTS; private Include() { } }
Include.Include.ALWAYS 預設
Include.NON_DEFAULT 屬性為預設值不序列化
Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化
Include.NON_NULL 屬性為NULL 不序列化
方式一:全域性配置,處理所有整個應用的實體物件
#對日期型別的轉換配置 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss # 配置 引數如下 always non_absent non_default non_empty non_null use_defaults spring.jackson.default-property-inclusion=non_null
方式二:在需要序列的話的實體類上加註解 ->[配置型別]所列
@JsonInclude(Include.NON_NULL)
方式三:配置型別
3.1自定義序列化實現類,可以作用在類上 自定義json序列化需要實現StdSerializer<T>或者JsonSerializer<T>
@JsonSerialize(using = ClientObjectSerialize.class) public class CreditBorrowerRepaymentRequestDto{ }
實現類:對欄位型別轉換,以及對值為null欄位的過濾
public class ClientObjectSerialize extends JsonSerializer<CreditBorrowerRepaymentRequestDto>{ @Override public void serialize(CreditBorrowerRepaymentRequestDto dto,JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException,JsonProcessingException { jsonGenerator.writeStartObject(); try { Field[] fields = dto.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); if(null == field.get(dto)){ continue; } jsonGenerator.writeFieldName(field.getName()); jsonGenerator.writeObject(field.get(dto)); } } catch (Exception e) { e.printStackTrace(); } jsonGenerator.writeEndObject(); } }
3.2自定義序列化實現類,可以作用在實體物件欄位上,對NULL值的處理,或者轉換
@JsonSerialize(using = ClientStringSerialize.class) private String name; @JsonSerialize(using = ClientDtaeSerialize.class) private Date date; public class ClientStringSerialize extends JsonSerializer<String> { @Override public void serialize(String string,SerializerProvider serializerProvider) throws IOException { if(string == null){ jsonGenerator.writeString(string + "[NULL]"); }else{ jsonGenerator.writeString(string); } } } public class ClientDtaeSerialize extends JsonSerializer<Date> { @Override public void serialize(Date createDate,SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createDate)); } }
實踐總結:
一當全域性配置了NULL欄位過濾的配置,但有的實體物件需要序列化出NULL的欄位值,如何處理?
答:
1. 直接在物件上增加 @JsonInclude(JsonInclude.Include.ALWAYS) 類上的註解優先順序比較高,會覆蓋全域性的配置
2.用自定義的類序列化註解(同上)
二直接在欄位上加自定義序列化類會覆蓋全域性配置嗎?
答:不會,有預設的 public class NullSerializer extends StdSerializer<Object> 來處理,當值不為Null的時候才會執行自定義欄位上的序列化註解實現類
補充知識:SpringBoot中Jackson返回null處理,字串型別轉空串,陣列集合轉[],物件轉{}
SpringBoot返回Json資料中null值處理,將字串型別null值轉換為"",將集合陣列型別null值轉換為[],將原始資料型別null值轉換為0,將布林型別null值轉換為false,將實體物件null值轉換為{}。
1.自定義null值序列化處理器
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; /** * 自定義null值序列化處理器 */ public class CustomizeNullJsonSerializer { /** * 處理陣列集合型別的null值 */ public static class NullArrayJsonSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value,SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartArray(); jsonGenerator.writeEndArray(); } } /** * 處理字串型別的null值 */ public static class NullStringJsonSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value,SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(""); } } /** * 處理數值型別的null值 */ public static class NullNumberJsonSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value,SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeNumber(0); } } /** * 處理boolean型別的null值 */ public static class NullBooleanJsonSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value,SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeBoolean(false); } } /** * 處理實體物件型別的null值 */ public static class NullObjectJsonSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value,SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartObject(); jsonGenerator.writeEndObject(); } } }
2.序列化程式修改器
import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; import java.util.Collection; import java.util.List; /** * <pre> * 此modifier主要做的事情為: * 1.當序列化型別為陣列集合時,當值為null時,序列化成[] * 2.String型別值序列化為"" * * </pre> */ public class MyBeanSerializerModifier extends BeanSerializerModifier { @Override public List<BeanPropertyWriter> changeProperties(SerializationConfig config,BeanDescription beanDesc,List<BeanPropertyWriter> beanProperties) { // 迴圈所有的beanPropertyWriter for (int i = 0; i < beanProperties.size(); i++) { BeanPropertyWriter writer = beanProperties.get(i); // 判斷欄位的型別,如果是陣列或集合則註冊nullSerializer if (isArrayType(writer)) { // 給writer註冊一個自己的nullSerializer writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullArrayJsonSerializer()); } if (isStringType(writer)) { writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullStringJsonSerializer()); } } return beanProperties; } /** * 是否是陣列 */ private boolean isArrayType(BeanPropertyWriter writer) { Class<?> clazz = writer.getType().getRawClass(); return clazz.isArray() || Collection.class.isAssignableFrom(clazz); } /** * 是否是String */ private boolean isStringType(BeanPropertyWriter writer) { Class<?> clazz = writer.getType().getRawClass(); return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz); } /** * 是否是數值型別 */ private boolean isNumberType(BeanPropertyWriter writer) { Class<?> clazz = writer.getType().getRawClass(); return Number.class.isAssignableFrom(clazz); } /** * 是否是boolean */ private boolean isBooleanType(BeanPropertyWriter writer) { Class<?> clazz = writer.getType().getRawClass(); return clazz.equals(Boolean.class); } }
3.配置Jackson實體
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; /** * 配置Jackson實體 */ @Configuration public class JacksonConfig { @Bean @Primary @ConditionalOnMissingBean(ObjectMapper.class) public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); /** 為objectMapper註冊一個帶有SerializerModifier的Factory */ objectMapper.setSerializerFactory(objectMapper.getSerializerFactory() .withSerializerModifier(new MyBeanSerializerModifier())); SerializerProvider serializerProvider = objectMapper.getSerializerProvider(); serializerProvider.setNullValueSerializer(new CustomizeNullJsonSerializer .NullObjectJsonSerializer()); return objectMapper; } }
以上這篇springboot專案中jackson-序列化-處理 NULL教程就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。