序列化
假如有 Clock
類:
public class Clock {
private LocalDate localDate;
private LocalTime localTime;
private LocalDateTime localDateTime;
// getter and setter
}
默認情況下, jackson序列化結果為:
{
"localDate": {
"year": 2017,
"month": "FEBRUARY",
"chronology": {
"calendarType": "iso8601",
"id": "ISO"
},
"era": "CE",
"dayOfYear": 57,
"dayOfWeek": "SUNDAY",
"leapYear": false,
"dayOfMonth": 26,
"monthValue": 2
},
"localTime": {
"hour": 17,
"minute": 33,
"second": 53,
"nano": 56000000
},
"localDateTime": {
"hour": 17,
"minute": 33,
"second": 53,
"nano": 56000000,
"dayOfYear": 57,
"dayOfWeek": "SUNDAY",
"month": "FEBRUARY",
"dayOfMonth": 26,
"year": 2017,
"monthValue": 2,
"chronology": {
"calendarType": "iso8601",
"id": "ISO"
}
}
}
簡直不能直視...
在添加 JSR-310 模塊后, 讓 jackson 能夠識別出 Java 8 的日期 & 時間類型(pom.xml
):
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
然后再啟用 ISO 8601格式化標准 后效果就好多了(application.properties
):
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
格式化效果:
{
"localDate": "2017-02-26",
"localTime": "17:42:54.141",
"localDateTime": "2017-02-26T17:42:54.141"
}
然而這中樣式不太符合日常使用習慣, 還是需要通過注解或自定義序列化類的方式實現定制. 這里采用注解的方式實現:
public class Clock {
private LocalDate localDate;
@JsonFormat(pattern = "HH:mm:ss")
private LocalTime localTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
// getter and setter
}
格式化效果:
{
"localDate": "2017-02-26",
"localTime": "17:45:06",
"localDateTime": "2017-02-26 17:45:06"
}
這樣就完美多了~
反序列化
上面只是序列化配置, 如果想提交日期參數還是配置一下:
public class Clock {
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate localDate;
@JsonFormat(pattern = "HH:mm:ss")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
private LocalTime localTime;
// @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
// getter and setter
}
DateTimeFormat.ISO.DATE_TIME
的格式是 yyyy-MM-dd'T'HH:mm:ss.SSSZ
(e.g. 2000-10-31T01:30:00.000-05:00
), 不太符合使用習慣, 因此需要自定義 pattern.
測試接口:
@RestController
@EnableAutoConfiguration
public class HomeController {
@RequestMapping("/clock")
public Object deserialization(Clock clock) {
if (null == clock.getLocalDate()) {
clock.setLocalDate(LocalDate.now());
}
if (null == clock.getLocalTime()) {
clock.setLocalTime(LocalTime.now());
}
if (null == clock.getLocalDateTime()) {
clock.setLocalDateTime(LocalDateTime.now());
}
return clock;
}
}
當請求 URL http://localhost:8080/clock?localDate=2017-01-01&localDateTime=2017-01-01%2001:01:01
時, 結果為:
{
"localDate": "2017-01-01",
"localTime": "17:53:34",
"localDateTime": "2017-01-01 01:01:01"
}
源碼
PS: Java 8 LocalDate mapping with mybatis