统一时间格式化
在开发过程,难免会遇到要求将时间统一格式化固定格式。接触过政企客户的同学,肯定有遇到要求格式为: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> 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 {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
if(value == null) {
jsonGenerator.writeStartObject();
jsonGenerator.writeEndObject();
}
}
}
/**
* 处理数组类型的null值
*/
public class NullArrayJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException, JsonProcessingException {
if (value == null) {
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
}
}
/**
* 处理日期类型的null为""
* */
public class NullDateJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
if(value == null) {
jsonGenerator.writeString("");
}
}
}
/**
* 处理字符串类型的null值
*/
public class NullStringJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeString("");
}
}
/**
* 处理数字类型的null值
*/
public class NullNumberJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeNumber(0);
}
}
/**
* 处理布尔类型的null值
*/
public class NullBooleanJsonSerializer extends JsonSerializer {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeBoolean(false);
}
}
public class MyBeanSerializerModifier extends BeanSerializerModifier {
@Override
public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List 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;
}
/**
* 是否是数组
*/
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);
}
/**
*
是否是int
*/
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);
}
/**
*
是否是Date
* */
private boolean isDateType(BeanPropertyWriter writer) {
Class> clazz = writer.getType().getRawClass();
return clazz.equals(Date.class);
}
}
/**
*
构造函数
* */
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> converters) {
converters.add(new MvcJsonConverter());
}
}