CLOVER🍀

That was when it all began.

Spring Boot+JacksonのDate and Time APIでフォーマットを変更する

Jacksonで、LocalDateTimeなどのDate and Time APIのクラスを使ってJSONを作成すると、デフォルトだと
ちょっと困ったことになります。

前提としてSpring Bootを使っているのですが、まずはpom.xmlに以下のように宣言。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

Date and Time API用に、「jackson-datatype-jsr310」を追加。

また「spring-boot-starter-web」を依存関係に追加すると、JacksonのObjectMapperがAutoConfigure対象と
なります。

これで、JSON変換対象にこんなクラスを用意して

import java.time.LocalDateTime;

public class Message {
    private String value;
    private LocalDateTime now;

    public Message() {
    }

    public Message(String value) {
        this.value = value;
        now = LocalDateTime.now();
    }

    public String getValue() {
        return value;
    }

    public LocalDateTime getNow() {
        return now;
    }
}

動作確認。

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SimpleTest {
    @Autowired
    ObjectMapper mapper;

    @Test
    public void localDateTime() throws Exception {
        System.out.println(mapper.writeValueAsString(new Message("Hello World")));
    }
}

すると、こんな感じのJSONが出力されます。

{"value":"Hello World","now":[2017,2,3,0,8,13,645000000]}

これはちょっと困りますね。

これを解決するには、application.propertiesを用意して以下のように設定します。
※ObjectMapperがAutoConfigure対象である必要があるみたいですが
src/main/resources/application.properties

spring.jackson.serialization.write-dates-as-timestamps=false

もしくは

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

すると、出力結果がこのように変化します。

{"value":"Hello World","now":"2017-02-03T00:10:23.967"}

良さそうですね。

フォーマットを指定したければ、@JsonFormatを使用すればよいみたいです。

import com.fasterxml.jackson.annotation.JsonFormat;

public class Message {
    private String value;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime now;

参考)
Spring Boot+周辺ライブラリでJava8日時APIを使う! (Java Advent Calendar 2015 4日目) - rakugakibox.net

Formatting Java Time with Spring Boot using JSON | Craftsmanship Archives

こんなところで。