Spring BootのJSON Java 8 LocalDateTime形式


112

Spring BootアプリケーションでJava 8 LocalDateTimeをフォーマットするときに小さな問題が発生します。「通常の」日付では問題ありませんが、LocalDateTimeフィールドは次のように変換されます。

"startDate" : {
    "year" : 2010,
    "month" : "JANUARY",
    "dayOfMonth" : 1,
    "dayOfWeek" : "FRIDAY",
    "dayOfYear" : 1,
    "monthValue" : 1,
    "hour" : 2,
    "minute" : 2,
    "second" : 0,
    "nano" : 0,
    "chronology" : {
      "id" : "ISO",
      "calendarType" : "iso8601"
    }
  }

私はそれを次のようなものに変換したいのですが:

"startDate": "2015-01-01"

私のコードは次のようになります:

@JsonFormat(pattern="yyyy-MM-dd")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
public LocalDateTime getStartDate() {
    return startDate;
}

ただし、上記のいずれのアノテーションも機能せず、日付は上記のようにフォーマットされ続けます。提案は大歓迎です!

回答:


134

update:Spring Boot 2.xでは、この設定は不要になりました。ここに最新の回答を書きまし


(これは、Spring Boot 2.xより前のバージョンの方法です。古いバージョンのSpring Bootで作業している場合に役立つ場合があります)

やっとここでそれを行う方法を見つけまし。それを修正するには、別の依存関係が必要でした:

compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.4.0")

この依存関係を含めることで、ここで説明するように、Springは自動的にコンバーターを登録します。その後、application.propertiesに以下を追加する必要があります。

spring.jackson.serialization.write_dates_as_timestamps=false

これにより、正しいコンバーターが使用され、日付が次の形式で印刷されます。 2016-03-16T13:56:39.492

注釈は、日付形式を変更する場合にのみ必要です。


24
-次の注釈を含む、おそらく価値が@JsonSerialize(using = LocalDateTimeSerializer.class)...
ニックGrealy

3
application.properties@patelbの回答で示唆されているように、おそらくエントリを使用する方が良いでしょう。
メンバーサウンド

機能していません。しかし、patelibの答えはそのまま使用できます。
Mykhaylo Kopytonenko 2017年

ヘッドアップとして、@JsonSerializeそれを機能させるためにニックが言及した注釈が必要でした。
pennstatephil 2018年

92

com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1依存関係を追加して、次の形式で日付の取得を開始しました。

"birthDate": [
    2016,
    1,
    25,
    21,
    34,
    55
  ]

それは私が欲しかったものではありませんが、私は近づいてきました。次に、以下を追加しました

spring.jackson.serialization.write_dates_as_timestamps=false

application.propertiesファイルに、必要な正しい形式を指定しました。

"birthDate": "2016-01-25T21:34:55"

2
jackson-datatype-jsr310依存関係を含めるとすぐに機能します。これは受け入れられる答えになるはずです。
メンバーサウンド2017

6
:あなたがObjectMapperを設定している場合FYI、application.properties部分は、Javaの設定を介して行うことができるようmapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
ジャスティン

31

ここではmavenにあり、このプロパティを使用すると、春のブーツのアップグレードの間に生き残ることができます

<dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
</dependency>

1
@NickGrealyコメントでこのソリューションを使用します。おそらく次の注釈を含める価値があります@JsonSerialize(using = LocalDateTimeSerializer.class)
HairOfTheDog

19

1)依存関係

 compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.8.8' 

2)日時形式の注釈。

public class RestObject {

    private LocalDateTime timestamp;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public LocalDateTime getTimestamp() {
        return timestamp;
    }
}

3)Spring Config。

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        System.out.println("Config is starting.");
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        return objectMapper;
    }
}

2
本当にありがとう。@JsonFormatは私のためにそれを解決したものです。上記の解決策のいずれも、何らかの理由で私にとってうまく
いか

7

任意の形式に変換してすべてのLocalDateTimeデータ型に適用できる別のソリューションを見つけました。すべてのLocalDateTimeデータ型の上に@JsonFormatを指定する必要はありません。最初に依存関係を追加します。

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

次のBeanを追加します。

@Configuration
public class Java8DateTimeConfiguration {
    /**
     * Customizing
     * http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html
     *
     * Defining a @Bean of type Jackson2ObjectMapperBuilder will allow you to customize both default ObjectMapper and XmlMapper (used in MappingJackson2HttpMessageConverter and MappingJackson2XmlHttpMessageConverter respectively).
     */
    @Bean
    public Module jsonMapperJava8DateTimeModule() {
        val bean = new SimpleModule();

        bean.addDeserializer (ZonedDateTime.class, new JsonDeserializer<ZonedDateTime>() {
            @Override
            public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return ZonedDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
            }
        });

        bean.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
            @Override
            public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return LocalDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            }
        });

        bean.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
            @Override
            public void serialize(
                    ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                    throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(zonedDateTime));
            }
        });

        bean.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
            @Override
            public void serialize(
                    LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                    throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDateTime));
            }
        });

        return bean;
    }
}

設定ファイルに以下を追加します:

@Import(Java8DateTimeConfiguration.class)

これにより、Springによって作成されたobjectMapperを使用している限り、すべてのプロパティLocalDateTimeおよびZonedDateTimeがシリアル化および非シリアル化されます。

ZonedDateTimeで取得した形式は、「2017-12-27T08:55:17.317 + 02:00 [Asia / Jerusalem]」で、LocalDateTimeは「2017-12-27T09:05:30.523」です。


おそらく、val BeanをSimpleModule bean = new SimpleModule();に置き換える必要があります。
Abhishek Galoda

これはJava 9用ですか?
Daniel Dai

@DanielDaiこれはJava 8です
Ida Amit

@Abhi、SimpleModule拡張しModuleます。Module抽象です。val bean = new SimpleModule(); 完璧に動作します。
Ida Amit

SpringBootバージョン1.5.3.RELEASEの場合、jackson-datatype-jsr310依存関係を追加する必要はありませんでした。
Moon13

7

私にも思い出させるためにこの答えを書いてください。

私はここでいくつかの答えを組み合わせ、最終的には私のようなもので動作しました。(私はSpringBoot 1.5.7とLombok 1.16.16を使用しています)

@Data
public Class someClass {

   @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
   @JsonSerialize(using = LocalDateTimeSerializer.class)
   @JsonDeserialize(using = LocalDateTimeDeserializer.class)
   private LocalDateTime someDate;

}

1
DateTimeFormat他の人のインポートを追加したい場合があります。
prayagupd

4

この作品はうまくいきます:

依存関係を追加します。

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>

注釈を追加します。

@JsonFormat(pattern="yyyy-MM-dd")

ここで、正しい形式を取得する必要があります。

オブジェクトマッパーを使用するには、JavaTimeを登録する必要があります

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());

1

すでに述べたように、spring-bootは必要なものをすべて取得します(webおよびwebfluxスターターの両方)。

しかし、さらに優れた点は、モジュールを自分で登録する必要がないことです。見てくださいここに。以来@SpringBootApplication使用@EnableAutoConfigurationフードの下で、その手段は、JacksonAutoConfiguration自動的にコンテキストに追加されます。さて、中を見るとJacksonAutoConfiguration、次のことがわかります。

    private void configureModules(Jackson2ObjectMapperBuilder builder) {
        Collection<Module> moduleBeans = getBeans(this.applicationContext,
                Module.class);
        builder.modulesToInstall(moduleBeans.toArray(new Module[0]));
    }

このフェラは初期化の過程で呼び出され、クラスパスで見つけることができるすべてのモジュールをフェッチします。(私はSpring Boot 2.1を使用しています)


1

Springboot 2.0.6を使用していますが、何らかの理由でアプリのymlの変更が機能しませんでした。そして、私はより多くの要件がありました。

ObjectMapperを作成してプライマリとしてマークしようとしましたが、スプリングブートにより、jacksonObjectMapperがすでにプライマリとしてマークされているという不満がありました。

これが私がしたことです。内部マッパーに変更を加えました。

私のシリアライザとデシリアライザは特別です-「dd / MM / YYYY」を扱います。逆シリアル化中-いくつかのLocalDateがあることを確認するために、3〜4の一般的な形式を使用するのが最善です。

@Autowired
ObjectMapper mapper;

@PostConstruct
public ObjectMapper configureMapper() {
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

    mapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, true);
    mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

    SimpleModule module = new SimpleModule();
    module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
    module.addSerializer(LocalDate.class, new LocalDateSerializer());
    mapper.registerModule(module);

    return mapper;
}

0

@JsonDeserialize(using= LocalDateDeserializer.class) 以下の依存関係では私にはうまくいきません。

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version> 2.9.6</version>
</dependency>

以下のコードコンバーターを使用して、日付をに逆シリアル化しましたjava.sql.Date

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;


@SuppressWarnings("UnusedDeclaration")
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<java.time.LocalDate, java.sql.Date> {


    @Override
    public java.sql.Date convertToDatabaseColumn(java.time.LocalDate attribute) {

        return attribute == null ? null : java.sql.Date.valueOf(attribute);
    }

    @Override
    public java.time.LocalDate convertToEntityAttribute(java.sql.Date dbData) {

        return dbData == null ? null : dbData.toLocalDate();
    }
}

0

単に使用してください:

@JsonFormat(pattern="10/04/2019")

またはあなたが好きなようにパターンを使用することができます例えば: ('-' in place of '/')


この回答は以前にも共有されていますが、正しい構文で共有されています。
Erik Pragt

0

Spring Boot 2.1.8を使用しています。輸入しました

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
</dependency>

これは含まれジャクソン・データ型-jsr310を

次に、これらの注釈を追加する必要がありました

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty("date")
LocalDateTime getDate();

そしてそれは動作します。JSONは次のようになります。

"date": "2020-03-09 17:55:00"

ヒント:インクルードは、欠落しているspring-boot-starter-json場合にのみ必要ですspring-boot-starter-web
柔道
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.