需求驱动
项目的restful接口返回响应参数的Date类型数据,需要灵活支持字符串格式的日期、long格式的日期(字符串形式返回,防止精度丢失),按需返回对应格式的日期类型的响应对象 |
需求分析
项目支持@JsonFormat(pattern = 'yyyy-MM-dd HH:mm:ss'), 已经满足返回 年月日的字符串格式日期了,需要考虑的就是实现返回long类型的日期,接口返回的是json格式的响应结果,所以考虑使用Jackson去修改返回对应日期类型的参数,启用该配置由AOP的注解来实现,可以做到灵活使用,互不影响 |
编码实现
日期格式返回Long格式----配置注解
import java.lang.annotation.*;
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DateFormatterToLong {
}
Date类型转Long的序列化:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;
public class LongSerializer extends JsonSerializer {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
Long output = null;
if (Objects.nonNull(date)) {
output = date.getTime();
}
jsonGenerator.writeString(String.valueOf(output.longValue()));
}
}
Date转Long格式化日期功能的具体实现:
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.opencv.annotation.DateFormatterToLong;
public class DateFormatterLongAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public Object findSerializer(Annotated annotated) {
DateFormatterToLong formatter = annotated.getAnnotation(DateFormatterToLong.class);
if (formatter != null) {
return new LongSerializer();
}
return super.findSerializer(annotated);
}
}
配置Date类型转Long时间戳格式:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opencv.formatter.DateFormatterLongAnnotationIntrospector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.nio.charset.StandardCharsets;
import java.util.TimeZone;
@Configuration
public class WebServerConfig {
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 不设置Utf-8格式,可能会导致Mock测试输出信息乱码
converter.setDefaultCharset(StandardCharsets.UTF_8);
ObjectMapper objectMapper = converter.getObjectMapper();
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.setAnnotationIntrospector(new DateFormatterLongAnnotationIntrospector());
return converter;
}
}
实体类设计:
import com.opencv.annotation.DateFormatterToLong;
import java.util.Date;
public class UserVO {
private String username;
private Integer sex;
//@JsonFormat(pattern = 'yyyy-MM-dd HH:mm:ss')
@DateFormatterToLong
private Date birthday;
// 省略getter setter
}
controller测试类:
import com.opencv.domain.vo.UserVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping('/date/formatter')
public class DateformatterController {
private static List userList = new ArrayList<>();
static {
UserVO userVO = new UserVO();
userVO.setUsername('张三');
userVO.setSex(1);
try {
userVO.setBirthday(new SimpleDateFormat('yyyy-MM-dd HH:mm:ss').parse('1993-03-13 10:00:00'));
userList.add(userVO);
userVO = new UserVO();
userVO.setUsername('李四');
userVO.setSex(1);
userVO.setBirthday(new SimpleDateFormat('yyyy-MM-dd HH:mm:ss').parse('1990-03-13 10:00:00'));
userList.add(userVO);
} catch (ParseException e) {
e.printStackTrace();
}
}
@GetMapping('/user/list')
@ApiOperation('获取用户列表数据')
public List queryUserList() {
return userList;
}
}
测试结果
测试获取‘年月日’的字符串格式日期:
测试获取long类型的字符串格式日期:
总结
数据格式化的原理类似于数据脱敏,就是利用接口返回的数据是json格式,在返回数据前,AOP对数据进行处理,返回对应要求格式化的数据,难点是适配多种场景做成通用的模块去处理
文章为作者独立观点,不代表股票交易接口观点