Spring Boot'ta JSON Java 8 LocalDateTime biçimi


112

Spring Boot Uygulamamda Java 8 LocalDateTime biçimlendirmeyle ilgili küçük bir sorun yaşıyorum. 'Normal' tarihlerle sorunum yok, ancak LocalDateTime alanları şu şekilde dönüştürülüyor:

"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"
    }
  }

Bunu şöyle bir şeye dönüştürmek isterken:

"startDate": "2015-01-01"

Kodum şöyle görünüyor:

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

Ancak yukarıdaki ek açıklamalardan herhangi biri çalışmıyor, tarih yukarıdaki gibi biçimlendirilmeye devam ediyor. Öneriler hoş geldiniz!

Yanıtlar:


135

güncelleme : Spring Boot 2.x artık bu yapılandırmayı gerektirmiyor. Burada daha güncel bir cevap yazdım .


(Bu, Spring Boot 2.x'ten önce yapmanın yoludur, Spring Boot'un eski bir sürümü üzerinde çalışan kişiler için yararlı olabilir)

Sonunda nasıl yapılacağını burada buldum . Düzeltmek için başka bir bağımlılığa ihtiyacım vardı:

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

Bu bağımlılığı dahil ederek, Spring burada açıklandığı gibi kendisi için otomatik olarak bir dönüştürücü kaydedecektir . Bundan sonra, application.properties dosyasına aşağıdakileri eklemeniz gerekir:

spring.jackson.serialization.write_dates_as_timestamps=false

Bu, doğru bir dönüştürücünün kullanılmasını sağlar ve tarihler şu biçimde yazdırılır: 2016-03-16T13:56:39.492

Ek açıklamalar yalnızca tarih formatını değiştirmek istediğinizde gereklidir.


25
Muhtemelen aşağıdaki ek açıklamayı @JsonSerialize(using = LocalDateTimeSerializer.class)
eklemeye

3
application.properties@Patelb cevabının önerdiği gibi, sadece bir girişi kullanmak muhtemelen daha iyidir .
membersound

Çalışmıyor. Ancak patelib'in cevabı kutudan çıkar çıkmaz işe yarar!
Mykhaylo Kopytonenko

Bir uyarı olarak, bizimkinin çalışması için @JsonSerializeNick'in bahsettiği ek açıklamaya ihtiyacı vardı .
pennstatephil

92

com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1Bağımlılığı ekledim ve tarihi şu formatta almaya başladım:

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

ki istediğim bu değildi ama yaklaşıyordum. Daha sonra aşağıdakileri ekledim

spring.jackson.serialization.write_dates_as_timestamps=false

Bana ihtiyacım olan doğru biçimi veren application.properties dosyasına.

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

2
jackson-datatype-jsr310Bağımlılık dahil edildiğinde kutudan çıkarıldı . Kabul edilen cevap bu olmalıdır.
membersound

6
Bilginize olarak, ObjectMapper'ı şu şekilde yapılandırıyorsanız, application.properties kısmı Java yapılandırması aracılığıyla yapılabilir:mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
justin

31

Burada maven'de, mülk ile birlikte, bahar önyükleme yükseltmeleri arasında hayatta kalabilirsiniz.

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

1
Bu çözümü @NickGrealy yorumuyla kullanın: Muhtemelen aşağıdaki ek açıklamayı @JsonSerialize(using = LocalDateTimeSerializer.class)
eklemeye

19

1) Bağımlılık

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

2) Tarih-saat formatına sahip açıklama.

public class RestObject {

    private LocalDateTime timestamp;

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

3) Yay Yapılandırması.

@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
Çok teşekkürler. @JsonFormat benim için çözen kişi. Yukarıdaki çözümlerden hiçbiri benim için herhangi bir nedenle işe yaramadı
programcı

7

İstediğiniz biçime dönüştürebileceğiniz ve tüm LocalDateTime veri türlerine uygulayabileceğiniz başka bir çözüm buldum ve her LocalDateTime veri türünün üzerinde @JsonFormat belirtmek zorunda değilsiniz. önce bağımlılığı ekleyin:

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

Aşağıdaki fasulyeyi ekleyin:

@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;
    }
}

yapılandırma dosyanıza aşağıdakileri ekleyin:

@Import(Java8DateTimeConfiguration.class)

Bu, spring tarafından oluşturulan objectMapper'ı kullandığınız sürece LocalDateTime ve ZonedDateTime tüm özelliklerini serileştirecek ve serileştirecektir.

ZonedDateTime için aldığınız biçim: LocalDateTime için "2017-12-27T08: 55: 17.317 + 02: 00 [Asya / Kudüs]" şeklindedir: "2017-12-27T09: 05: 30.523"


Olasılıkla val bean'i SimpleModule bean olarak değiştirmeniz gerekir = new SimpleModule ();
Abhishek Galoda

Bu Java 9 için mi?
Daniel Dai

@DanielDai Bu Java 8'de.
Ida Amit

@Abhi, SimpleModulegenişler Module. Modulebir soyuttur. val bean = new SimpleModule(); mükemmel çalışıyor.
Ida Amit

SpringBoot sürüm 1.5.3 için. jackson-datatype-jsr310 bağımlılığını eklemek için RELEASE gerekli değildi.
Ay13

7

Bu cevabı benim için de bir hatırlatma olarak yazmak.

Burada birkaç cevabı birleştirdim ve sonunda benimki buna benzer bir şeyle çalıştı. (SpringBoot 1.5.7 ve Lombok 1.16.16 kullanıyorum)

@Data
public Class someClass {

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

}

1
DateTimeFormatve diğerleri için ithalat eklemek isteyebilirsiniz .
duaagupd

4

Bu iyi çalışıyor:

Bağımlılığı ekleyin:

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

Ek açıklamayı ekleyin:

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

Şimdi, doğru formatı almalısınız.

Nesne eşleyiciyi kullanmak için JavaTime'ı kaydetmeniz gerekir

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

1

Daha önce de belirtildiği gibi, yaylı önyükleme ihtiyacınız olan her şeyi getirecektir (hem web hem de webflux başlangıç ​​için).

Ama daha da iyisi - herhangi bir modülü kendiniz kaydetmenize gerek yok. Buraya bir göz atın . Yana @SpringBootApplicationkullanımlar @EnableAutoConfigurationbaşlık altında, yani cihazın JacksonAutoConfigurationotomatik bağlama eklenecektir. Şimdi, içine bakarsanız şunu JacksonAutoConfigurationgöreceksiniz:

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

Bu arkadaş , başlatma sürecinde çağrılacak ve sınıf yolunda bulabildiği tüm modülleri getirecektir. (Spring Boot 2.1 kullanıyorum)


1

Springboot 2.0.6 kullanıyorum ve bazı nedenlerden dolayı, uygulama yml değişiklikleri işe yaramadı. Ayrıca daha çok ihtiyacım vardı.

ObjectMapper oluşturmayı ve onu Birincil olarak işaretlemeyi denedim, ancak ilkbahar önyüklemesi zaten jacksonObjectMapper'ın Primary olarak işaretlendiğinden şikayet etti !!

Ben de öyle yaptım. Dahili eşleyicide değişiklikler yaptım.

Serileştiricim ve Seri Çözücüm özeldir - 'gg / AA / YYYY' ile ilgilenirler; ve serileştirme sırasında - biraz LocalDate'e sahip olduğumdan emin olmak için 3-4 popüler formatı kullanmaya çalışıyor.

@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) benim için aşağıdaki bağımlılıkla çalışmıyor.

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

Tarihi bir 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

basitçe şunu kullanın:

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

veya istediğiniz gibi desen kullanabilirsiniz, örneğin: ('-' in place of '/')


Bu cevap daha önce paylaşıldı, ancak daha sonra doğru sözdizimi ile.
Erik Pragt

0

Spring Boot 2.1.8 kullanıyorum. İthal ettim

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

ki içerir Jackson-veri türü-jsr310 .

Sonra bu ek açıklamaları eklemek zorunda kaldım

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

ve çalışıyor. JSON şuna benzer:

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

İpucu: dahil etme spring-boot-starter-jsonyalnızca spring-boot-starter-webeksikse gereklidir .
judomu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.