web-dev-qa-db-ja.com

Spring BootでのJSON Java 8 LocalDateTimeフォーマット

私の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;
}

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

91
Erik Pragt

update:Spring Boot 2.xでは、この設定はもう必要ありません。私は書きました もっと最新の答えはここに


(これはSpring Boot 2.xより前のやり方ですが、Spring Bootの古いバージョンを扱っている人には便利かもしれません)

私はついに ここ それをどうやってやるのか見つけました。それを修正するために、私は別の依存関係を必要としました:

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

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

spring.jackson.serialization.write_dates_as_timestamps=false

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

注釈は日付フォーマットを変更したい場合にのみ必要です。

117
Erik Pragt

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"
81
patelb

あなたは春のブーツのアップグレードの間に生き残ることができるように、ここでそれはプロパティで、mavenにあります

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

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)春の設定。

@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;
    }
}
11
Yan Khonski

私はあなたがそれをあなたが望むすべての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 [アジア/エルサレム]"です。LocalDateTimeの形式は、「2017-12-27T09:05:30.523」です。

7
Ida Amit

これはうまくいきます:

依存関係を追加します。

<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());
3
Manuel Antonio

私にも念のためにこの答えを書いてください。

私はここでいくつかの答えを組み合わせ、そして結局私のものはこれらのようなもので働いた。 (私は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;

}
3
JWiryo

すでに述べたように、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]));
    }

this fella は初期化の過程で呼ばれ、クラスパスにある全てのモジュールを取得します。 (私はSpring Boot 2.1を使っています)

1
yuranos87

私は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;
    }
1
Kalpesh Soni

@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
Ram

単に使用する:

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

あるいは、あなたは好きなようにpatternを使うことができます。例えば:('-' in place of '/')

0
Ashish Dwivedi