序列化和反序列化Java 8的時間/日期類


序列化

假如有 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"
}

源碼

Github

PS: Java 8 LocalDate mapping with mybatis

參考鏈接:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM