स्प्रिंग बूट में JSON Java 8 LocalDateTime प्रारूप


112

मुझे अपने स्प्रिंग बूट एप्लिकेशन में 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

अपडेट : स्प्रिंग बूट 2.x को अब इस कॉन्फ़िगरेशन की आवश्यकता नहीं है। मैंने यहाँ पर अधिक उत्तर देने के लिए लिखा है


(यह स्प्रिंग बूट 2.x से पहले करने का तरीका है, यह स्प्रिंग बूट के पुराने संस्करण पर काम करने वाले लोगों के लिए उपयोगी हो सकता है)

मैं अंत में यहाँ पाया कि यह कैसे करना है। इसे ठीक करने के लिए, मुझे एक और निर्भरता की आवश्यकता थी:

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

इस निर्भरता को शामिल करके, स्प्रिंग स्वचालित रूप से इसके लिए एक कनवर्टर पंजीकृत करेगा, जैसा कि यहां वर्णित है । उसके बाद, आपको application.properties में निम्नलिखित जोड़ना होगा:

spring.jackson.serialization.write_dates_as_timestamps=false

यह सुनिश्चित करेगा कि एक सही कनवर्टर का उपयोग किया जाता है, और तिथियों को प्रारूप में मुद्रित किया जाएगा 2016-03-16T13:56:39.492

यदि आप दिनांक प्रारूप को बदलना चाहते हैं तो केवल एनोटेशन की आवश्यकता है।


24
संभवतः निम्नलिखित एनोटेशन सहित - @JsonSerialize(using = LocalDateTimeSerializer.class)...
निक ग्रीली

3
शायद केवल एक application.propertiesप्रविष्टि का उपयोग करना बेहतर है , जैसा कि @patelb उत्तर द्वारा सुझाया गया है।
मेंबर

काम नहीं कर रहा। लेकिन patelib का जवाब सिर्फ बॉक्स से बाहर है!
मीकायलो कोप्पटनेंको

एक मुखिया के रूप में, हमारा काम करने के लिए @JsonSerializeएनोटेशन निक का उल्लेख किया गया था।
पेन्न्स्टेटेटिल

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

to application.properties फ़ाइल जिसने मुझे सही प्रारूप दिया जिसकी मुझे आवश्यकता थी।

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

2
jackson-datatype-jsr310निर्भरता शामिल होने पर बॉक्स से बाहर काम किया । यह स्वीकृत उत्तर होना चाहिए।
मेंबर

6
एक FYI करें, application.properties हिस्सा जावा config के माध्यम से किया जा सकता है के रूप में आप के साथ ObjectMapper को कॉन्फ़िगर करते हैं:mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
जस्टिन

31

यहां यह मावेन में है, संपत्ति के साथ ताकि आप वसंत बूट उन्नयन के बीच जीवित रह सकें

<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) वसंत विन्यास।

@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 वह है जिसने इसे मेरे लिए हल किया है। उपरोक्त समाधानों में से किसी ने भी किसी कारण से मेरे लिए काम नहीं किया है
theprogrammer

7

मुझे एक और समाधान मिला, जिसे आप जो चाहें प्रारूप में परिवर्तित कर सकते हैं और सभी LocalDateTime डेटाटाइप पर लागू कर सकते हैं और आपको प्रत्येक LocalDateTime डेटाटाइप के ऊपर @JsonFormat निर्दिष्ट करने की आवश्यकता नहीं है। पहले निर्भरता जोड़ें:

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

निम्नलिखित सेम जोड़ें:

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

यह सभी प्रॉपर्टीज LocalDateTime और ZonedDateTime को तब तक सीरियल और डी-सीरियल करेगा, जब तक कि आप स्प्रिंग द्वारा बनाई गई ऑब्जेक्टमैपर का उपयोग कर रहे हैं।

ज़ोनडेडटाइम के लिए आपको जो प्रारूप मिला है वह है: "2017-12-27T08: 55: 17.317 + 02: 00 [एशिया / यरुशलम]" के लिए LocalDateTime है: "2017-12-27T09: 05: 30.523"


प्रोबाइबल आपको वैल बीन को सिंपलमॉडल बीन = नए सिंपलमॉडल () से बदलने की आवश्यकता है;
अभिषेक गालोदा

यह जावा 9 Is के लिए है
डैनियल दाई

@DanielDai यह जावा 8 में है
इडा अमित

@ आभा, SimpleModuleफैली हुई है ModuleModuleएक सार है। val bean = new SimpleModule(); सही काम करता है।
इडा अमित

स्प्रिंगबूट संस्करण 1.5.3 के लिए। जैकसन-डेटाटाइप- jsr310 निर्भरता को जोड़ने के लिए आवश्यक नहीं था।
मून 13

7

इस उत्तर को मेरे लिए भी एक अनुस्मारक के रूप में लिखना।

मैंने कई उत्तरों को यहां जोड़ा और अंत में मेरा काम कुछ इस तरह से हुआ। (मैं स्प्रिंगबूट 1.5.7 और लोम्बोक 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अन्य लोगों के लिए आयात जोड़ना चाह सकते हैं ।
प्रयागपाद

4

यह काम ठीक है:

निर्भरता जोड़ें:

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

एनोटेशन जोड़ें:

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

अब, आपको सही प्रारूप प्राप्त करना होगा।

ऑब्जेक्ट मैपर का उपयोग करने के लिए, आपको जावाटाइम रजिस्टर करना होगा

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

1

जैसा कि पहले ही उल्लेख किया गया है, वसंत-बूट आपको सभी की आवश्यकता होगी (वेब ​​और वेबफ्लक्स स्टार्टर दोनों के लिए)।

लेकिन इससे भी बेहतर - आपको स्वयं किसी भी मॉड्यूल को पंजीकृत करने की आवश्यकता नहीं है। यहाँ एक नज़र रखना । चूंकि हुड के तहत @SpringBootApplicationउपयोग @EnableAutoConfigurationहोता है, इसका मतलब यह JacksonAutoConfigurationस्वचालित रूप से संदर्भ में जोड़ा जाएगा। अब, यदि आप अंदर JacksonAutoConfigurationदेखते हैं , तो आप देखेंगे:

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

इस फेला को आरंभीकरण की प्रक्रिया में कहा जाएगा और यह सभी मॉड्यूल को प्राप्त करेगा जो इसे क्लासपाथ में पा सकते हैं। (मैं स्प्रिंग बूट 2.1 का उपयोग करता हूं)


1

मैं स्प्रिंगबूट 2.0.6 का उपयोग कर रहा हूं और किसी कारण से, ऐप yml में बदलाव नहीं हुआ। और मुझे भी अधिक आवश्यकताएं थीं।

मैंने ObjectMapper बनाने और इसे प्राथमिक के रूप में चिह्नित करने की कोशिश की, लेकिन स्प्रिंग बूट ने शिकायत की कि मेरे पास पहले से ही jacksonObjectMapper है जो प्राथमिक के रूप में चिह्नित है !!

तो यही वह है जो मैंने किया। मैंने आंतरिक मैपर में परिवर्तन किए।

मेरे सीरियलाइज़र और डिसेरिएलाइज़र विशेष हैं - वे 'dd / MM / YYYY' के साथ काम करते हैं; और डी-क्रमांकन करते समय - यह सुनिश्चित करने के लिए 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 '/')


यह उत्तर पहले साझा किया गया है, लेकिन फिर सही सिंटैक्स के साथ।
एरिक प्रैग

0

मैं स्प्रिंग बूट 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लापता है।
जुडोमू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.