Springboot:返回客戶端的json統一時間格式化及統一處理Null值

統一時間格式化

在開發過程,難免會遇到要求將時間統一格式化固定格式。接觸過政企客戶的同學,肯定有遇到要求格式爲:xxxx年xx月xx日 00:00:00這種。如果依依改動,會消耗大量工作。

springboot默認使用的json轉換器是Jackson。(以下方式不支持fastjson或其他轉換器)

方式一:在每個返回的視圖對象中使用註解。(缺點:太繁瑣,每個地方都需要使用。但是它的優先級最高,所以在有特殊要求的地方可以適當使用,否則應該全局統一處理)

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

註解常用屬性:pattern:日期格式;timezone:時區。

方式二:使用配置文件

# 時間格式
spring.jackson.date-format = yyyy-MM-dd HH:mm:ss
# 時區
spring.jackson.time-zone= GMT+8
# 不返回時間戳
spring.jackson.serialization.write-dates-as-timestamps=false

注意:如果有配置類繼承了WebMvcConfigurationSupport,那麼以上配置將不會生效。(可以更改爲實現WebMvcConfigurer接口)

方式三:重寫MappingJackson2HttpMessageConverter

@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {

	@Override
	protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
		ObjectMapper objectMapper = jacksonConverter.getObjectMapper();
		// 忽略未知屬性 
	    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	    // 設置時間格式(時間格式可以通過配置文件獲取,增加靈活度)
	    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
	    jacksonConverter.setObjectMapper(objectMapper);
		converters.add(jacksonConverter);
	}
}

統一處理Null值

在開發中,如果從數據庫或第三方接口獲取的數據爲null,未經處理直接返回客戶端.那麼最終的json會像這樣:

{
    "name": "null"
}

而正確的應該是:

{
    "name": ""
}

如果單處處理,需要這樣做:

user.setName(name == null ? "" : name);

但是,一個項目成千上萬的代碼,而且難免會有遺漏。所以,需要一個統一處理的地方。因springboot默認使用的序列化工具是jackson。裝配的轉換器是MappingJackson2HttpMessageConverter,所以,還是直接在MappingJackson2HttpMessageConverter上面做文章即可。

public class MvcJsonConverter extends MappingJackson2HttpMessageConverter {

	public class NullBeanJsonSerializer extends JsonSerializer<Object> {

		@Override
		public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
			if(value == null) {
				jsonGenerator.writeStartObject();
				jsonGenerator.writeEndObject();
			}
		}
	}
	
	
	/**
     * <p>處理數組類型的null值
     */
    public class NullArrayJsonSerializer extends JsonSerializer<Object> {
 
        @Override
        public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException, JsonProcessingException {
        	if (value == null) {
            	jsonGenerator.writeStartArray();
            	jsonGenerator.writeEndArray();
            }
        }
    }
 
    /**
     * <p>處理日期類型的null爲""
     * */
    public class NullDateJsonSerializer extends JsonSerializer<Object> {

		@Override
		public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
			if(value == null) {
				jsonGenerator.writeString("");
			}
		}
    	
    }
 
    /**
     * <p>處理字符串類型的null值
     */
    public class NullStringJsonSerializer extends JsonSerializer<Object> {
 
        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        	jsonGenerator.writeString("");
        }
    }
 
    /**
     * <p>處理數字類型的null值
     */
    public class NullNumberJsonSerializer extends JsonSerializer<Object> {
 
        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeNumber(0);
        }
    }
 
    /**
     * <p>處理布爾類型的null值
     */
    public class NullBooleanJsonSerializer extends JsonSerializer<Object> {
 
        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeBoolean(false);
        }
    }
 
    public class MyBeanSerializerModifier extends BeanSerializerModifier {
 
 
        @Override
        public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
        	//循環所有的beanPropertyWriter
            for (Object beanProperty : beanProperties) {
            	BeanPropertyWriter writer = (BeanPropertyWriter) beanProperty;
            	//判斷字段的類型,如果是array,list,set則註冊nullSerializer
                if (isArrayType(writer)) {
                    //給writer註冊一個自己的nullSerializer
                    writer.assignNullSerializer(new NullArrayJsonSerializer());
                } else if (isNumberType(writer)) {
                    writer.assignNullSerializer(new NullNumberJsonSerializer());
                } else if (isBooleanType(writer)) {
                    writer.assignNullSerializer(new NullBooleanJsonSerializer());
                } else if (isStringType(writer)) {
                    writer.assignNullSerializer(new NullStringJsonSerializer());
                }else if(isDateType(writer)) {
                	writer.assignNullSerializer(new NullDateJsonSerializer());
                }else {
                	writer.assignNullSerializer(new NullBeanJsonSerializer());
                }
            }
            return beanProperties;
        }
 
        /**
         * <p>是否是數組
         */
        private boolean isArrayType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
        }
 
        /**
         * <p>是否是string
         */
        private boolean isStringType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
        }
 
        /**
         * <p>是否是int
         */
        private boolean isNumberType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return Number.class.isAssignableFrom(clazz);
        }
 
        /**
         * <p>是否是boolean
         */
        private boolean isBooleanType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return clazz.equals(Boolean.class);
        }
        
        /**
         * <p>是否是Date
         * */
        private boolean isDateType(BeanPropertyWriter writer) {
        	Class<?> clazz = writer.getType().getRawClass();
        	return clazz.equals(Date.class);
        }
    }
 
    /**
     * <p>構造函數
     * */
    MvcJsonConverter() {
        getObjectMapper().setSerializerFactory(getObjectMapper().getSerializerFactory().withSerializerModifier(new MyBeanSerializerModifier()));
        // 日期統一格式化(優先級低於在視圖對象使用註解格式化或在代碼中格式化)
        ObjectMapper objectMapper = super.getObjectMapper();
	    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
	    setObjectMapper(objectMapper);
    }
}
@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {

	@Override
	protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		converters.add(new MvcJsonConverter());
	}
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章