統一時間格式化
在開發過程,難免會遇到要求將時間統一格式化固定格式。接觸過政企客戶的同學,肯定有遇到要求格式爲: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());
}
}