LocalDateTime在spring boot中的格式化配置


在項目中日期格式化是最常見的問題,之前涉及的 java.util.Date 和 java.util.Calendar 類易用性差,不支持時區,非線程安全,對日期的計算方式繁瑣,而且容易出錯,因為月份是從0開始的,從 Calendar 中獲取的月份需要加一才能表示當前月份。

在 JDK8 中,一個新的重要特性就是引入了全新的時間和日期API,它被收錄在 java.time 包中,借助新的時間和日期API可以以更簡潔的方法處理時間和日期。

下面我們通過一些配置實現對日期類型LocalDateTime的格式化

導入依賴

新建一個spring boot項目導入web依賴即可

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

配置方案一

定義一個配置類,在里面定義兩個 Bean 即可完成全局日期格式化處理,同時還兼顧了 Date 和 LocalDateTime 並存

package com.carry.config;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

@Configuration
public class LocalDateTimeSerializerConfig {

    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

     // 方案一
    @Bean 
    public LocalDateTimeSerializer localDateTimeDeserializer() { 
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)); 
    }
      
    @Bean 
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { 
        return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer()); 
    }

}

 

實體類

package com.carry.dto;

import java.time.LocalDateTime;

public class Order {

    private LocalDateTime createTime;

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
    
}

 

控制層

package com.carry.controller;

import java.time.LocalDateTime;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.carry.dto.Order;

@RestController
@RequestMapping("/orders")
public class OrderController {

    @GetMapping
    public Order query() {
        Order order = new Order();
        order.setCreateTime(LocalDateTime.now());
        return order;
    }
}

測試

啟動項目並在瀏覽器中訪問 http://localhost:8080/orders

 

配置方案二

有時候,我們對日期格式要做特殊的處理,全局的格式化方式無法滿足我們需求是,使用該方案是非常好的選擇,通過 @JsonFormat 注解我們可以更為精准的為日期字段格式化,它的優先級比方案一高,二者可結合使用

package com.carry.dto;

import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;

public class Order {

    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDateTime createTime;

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
    
}

重新啟動項目並在瀏覽器中訪問 http://localhost:8080/orders

配置方案三

其實和第一種類似,只不過第一種的寫法更加優雅簡潔,如果有多種類型需要做統一格式化處理,這種方案也不是不可以考慮(經測試不能與方案二同時使用)

package com.carry.config;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

@Configuration
public class LocalDateTimeSerializerConfig {

    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    // 方案三
    @Bean
    @Primary
    public ObjectMapper serializingObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }

    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException {
            gen.writeString(value.format(DateTimeFormatter.ofPattern(pattern)));
        }
    }

    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
                throws IOException {
            return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern));
        }
    }
}

訪問 http://localhost:8080/orders,發現 @JsonFormat 配置無效

 推薦使用方案一與方案二


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM