在日期的格式化过程中,我们有时候需要将日期格式化到秒或者微妙,有时候又仅仅需要将日期格式化到日期,所以定义全局的日期格式化肯定难以满足需求,这时就需要一种更灵活的方法。
在Spring Boot对JSON的处理类中,定义了annotationIntrospector属性,专用于处理注解,因此自定义日期格式化的步骤分为四步,如下:
1. 定义日期格式化注解,用于盛放格式化样式;
2. 定义日期JSON串行化化处理类;
3. 定义注解处理类;
4. 配置Spring容器;
1. 定义注解
此注解只需要知道日期格式化的样式即可,如“YYYY-MM-dd”,所以只需要一个配置属性即可,如下:
@Target( {ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DateFormatter {
// 用于储存日期格式化样式
String value() default "yyyy-MM-dd";
}
2. 定义JSON串行化处理类
通过注解获取到了日期格式化样式,又有了日期的输入值,现在就可以进行JSON串行化了,如下;
public class DateTimeSerializer extends JsonSerializer<Date> {
// 用于储存日期串行化格式
private final String key;
/**
* @param key
*/
public DateTimeSerializer(String key) {
super();
this.key = key;
}
/* (non-Javadoc)
* @see com.fasterxml.jackson.databind.JsonSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
*/
@Override
public void serialize(Date value, JsonGenerator jgen,
SerializerProvider provider)
throws IOException, JsonProcessingException {
String output = StringUtils.EMPTY;
if(value != null) {
// 将日期转换为字符串
output = new SimpleDateFormat(key).format(value);
}
// 输出转换结果
jgen.writeString(output);
}
}
3. 定义注解处理类
JAVA对象转换JSON字符串的处理类ObjectMapper可以定义方法、属性的JSON转换过程,如下:
public class MyAnnotationIntrospector extends JacksonAnnotationIntrospector {
/* (non-Javadoc)
* @see com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector#findSerializer(com.fasterxml.jackson.databind.introspect.Annotated)
*/
@Override
public Object findSerializer(Annotated annotated) {
// 经测试,只对方法有用
if(annotated instanceof AnnotatedMethod) {
DateFormatter formatter = annotated.getAnnotated().getAnnotation(DateFormatter.class);
if(formatter != null) {
return new DateTimeSerializer(formatter.value());
}
}
return super.findSerializer(annotated);
}
}
在我的测试中,好像只对方法上的注解有效(即getter上的注解)。
4. 配置Spring容器
配置又分为两步,一是配置ObjectMapper,如下:
<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="annotationIntrospector">
<bean class="com.mirana.json.MyAnnotationIntrospector"/>
</property>
</bean>
二是配置HTTP消息转换器,如下:
<mvc:annotation-driven validator="validator">
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
现在可以直接应用注解了,每个属性都可以格式化为不同的输出,如下:
// 默认的短格式
@DateFormatter
public Date getClient_time() {
return client_time;
}
// 更换为长格式
@DateFormatter("yyyy-MM-dd HH:mm:ss")
public Date getClient_time() {
return client_time;
}
结论
通过使用注解,可以自定义日期的格式化样式,降低类型转换的工作量。