统一时间格式化

在开发过程,难免会遇到要求将时间统一格式化固定格式。接触过政企客户的同学,肯定有遇到要求格式为: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());
	}
	
}

 

 

Logo

新一代开源开发者平台 GitCode,通过集成代码托管服务、代码仓库以及可信赖的开源组件库,让开发者可以在云端进行代码托管和开发。旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐