spring boot 與 jdk8 LocalDate LocalDateTime集成

[TOC]

spring boot 與 jdk8 LocalDate LocalDateTime集成

  1. pom.xml
    重點(diǎn)是 加入依賴jackson-datatype-jsr310

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

完整pom.xml 如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dennis</groupId>
    <artifactId>demoboot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-parameter-names</artifactId>
            <version>2.9.9</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jdk8</artifactId>
            <version>2.9.9</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.9.9</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>

</project>

  1. 添加JDK8 LocalDATE增強(qiáng)序列化生成器
package com.dennis.da.config;

import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/** Converter 不可優(yōu)化使用Lambda表達(dá)式袖订,否則會(huì)出現(xiàn)啟動(dòng)失敗的問題 
 * @author dennis*/
@Configuration
public class LocalDateTimeSerializerConfig {
    private static DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); //
    private static DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");

    /** String --> LocalDate */
    @Bean
    public Converter<String, LocalDate> localDateConverter() {
        return new Converter<String, LocalDate>() {
            @Override
            public LocalDate convert(@NotNull String source) {
                if (StringUtils.hasText(source)) {
                    return LocalDate.parse(source, DATE_FORMATTER);
                }
                return null;
            }
        };
    }

    /** String --> LocalDatetime */
    @Bean
    public Converter<String, LocalDateTime> localDateTimeConverter() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(@NotNull String source) {
                if (StringUtils.hasText(source)) {
                    return LocalDateTime.parse(source, DATE_TIME_FORMATTER);
                }
                return null;
            }
        };
    }

    /** String --> LocalTime */
    @Bean
    public Converter<String, LocalTime> localTimeConverter() {
        return new Converter<String, LocalTime>() {
            @Override
            public LocalTime convert(@NotNull String source) {
                if (StringUtils.hasText(source)) {
                    return LocalTime.parse(source, TIME_FORMATTER);
                }
                return null;
            }
        };
    }

    @Bean
    @Primary
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER))
                .serializerByType(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER))
                .serializerByType(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER))
                .deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER))
                .deserializerByType(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER))
                .deserializerByType(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
    }


    /** Json序列化和反序列化轉(zhuǎn)換器,用于轉(zhuǎn)換Post請(qǐng)求體中的json以及將我們的對(duì)象序列化為返回響應(yīng)的json */
//    @Bean
//    public ObjectMapper objectMapper() {
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//        objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
//
//        // LocalDateTime系列序列化模塊,繼承自jsr310幽七,我們?cè)谶@里修改了日期格式
//        JavaTimeModule javaTimeModule = new JavaTimeModule();
//        javaTimeModule.addSerializer(
//                LocalDateTime.class,
//                new JsonSerializer<LocalDateTime>() {
//                    @Override
//                    public void serialize(
//                            LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
//                            throws IOException {
//                        String format =
//                                value.atZone(ZoneOffset.UTC).format(DATE_TIME_FORMATTER);
//                        gen.writeString(format);
//                    }
//                });
//
//        javaTimeModule.addSerializer(
//                LocalDate.class,
//                new JsonSerializer<LocalDate>() {
//                    @Override
//                    public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers)
//                            throws IOException {
//                        String format = value.format(DATE_FORMATTER);
//                        gen.writeString(format);
//                    }
//                });
//
//        objectMapper.registerModule(javaTimeModule);
//        return objectMapper;
//    }
}

  1. 其他代碼
    3.1. Order.java
package com.dennis.da.controller;

import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;

public class Order implements Serializable {

    private final static long serialVersionUID = 1L;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    private LocalDate createDate;

    public LocalDateTime getCreateTime() {
        return createTime;
    }

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

    public LocalDate getCreateDate() {
        return createDate;
    }

    public void setCreateDate(LocalDate createDate) {
        this.createDate = createDate;
    }

    @Override
    public String toString() {
        return "Order{" +
                "createTime=" + createTime +
                ", createDate=" + createDate +
                '}';
    }
}

3.2. Controller

package com.dennis.da.controller;

import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by dennis on 2020-3-27.
 */
@RequestMapping("dt")
@RestController
public class DtController {

    /**
     *
     {
     "date": "2020-03-29",
     "time": "19:30:54.468",
     "ldt": "2020-03-29 19:30:54"
     }
     * @return
     */
    @GetMapping("now")
    public Map<String, Object> nowDate() {
        Map<String, Object> map = new HashMap<>();
        map.put("date", LocalDate.now());
        map.put("time", LocalTime.now());
        map.put("ldt", LocalDateTime.now());
        return map;
    }

    @GetMapping("ld")
    public LocalDate localDate(
            @RequestParam
            @DateTimeFormat(pattern = "yyyy-MM-dd")
                    LocalDate lc) {

        System.out.println(lc.toString());
        return lc;
    }

    @GetMapping("ldt")
    public LocalDateTime localDatetime(
            @RequestParam
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
                    LocalDateTime lc) {
        System.out.println(lc.toString());
        return lc;
    }

    @GetMapping("lt")
    public LocalTime locatime(
            @RequestParam
            @DateTimeFormat(pattern = "HH:mm:ss")
                    LocalTime lc) {
        System.out.println(lc.toString());
        return lc;
    }

    @JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy.MM.dd HH:mm:ss")
    @GetMapping("json-now")
    public LocalDateTime dtmLocalDt(
            @RequestParam
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
                    LocalDateTime lc
    ) {
        return lc;
    }

    @GetMapping("order")
    public Order koder() {
        Order or = new Order();
        or.setCreateTime(LocalDateTime.now());
        or.setCreateDate(LocalDate.now());
        return or;
    }
    @GetMapping("order3")
    public Order koder2(@RequestParam LocalDateTime createTime, @RequestParam LocalDate createDate) {
        Order or = koder();
        return or;
    }
    @PostMapping(value = "order2")
    public Order sss(@RequestBody Order order) {
        System.out.println(order);
        Order or = koder();
        return or;
    }

}

4 輸出結(jié)果
rest-api.http

GET http://localhost:8080/dt/now
Accept: */*
Cache-Control: no-cache

輸出:<> 2020-03-30T102014.200.json
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Date: Mon, 30 Mar 2020 02:20:14 GMT

{
  "date": "2020-03-30",
  "time": "10:20:14",
  "ldt": "2020-03-30 10:20:14"
}


###
GET http://localhost:8080/dt/ld?lc=2019-12-22
Accept: */*
Cache-Control: no-cache

輸出: <> 2020-03-30T101206.200.json
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Date: Mon, 30 Mar 2020 02:28:56 GMT

"2019-12-22"

Response code: 200 (OK); Time: 40ms; Content length: 12 bytes


###
GET http://localhost:8080/dt/ldt?lc=2019-12-22 13:44:55
Accept: */*
Cache-Control: no-cache

輸出:<> 2020-03-30T101211.200.json
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Date: Mon, 30 Mar 2020 02:29:18 GMT

"2019-12-22 13:44:55"

Response code: 200 (OK); Time: 29ms; Content length: 21 bytes

###

GET http://localhost:8080/dt/lt?lc=13:44:55
Accept: */*
Cache-Control: no-cache

輸出:<> 2020-03-30T101216.200.json
"13:44:55"


###

GET http://localhost:8080/dt/json-now?lc=2019-12-22 13:44:55
Accept: */*
Cache-Control: no-cache

輸出:<> 2020-03-30T101220.200.json
"2019-12-22 13:44:55"


###
GET http://localhost:8080/dt/order
Accept: */*
Cache-Control: no-cache

輸出:<> 2020-03-30T101224.200.json
{
  "createTime": "2020-03-30 10:14:52",
  "createDate": "2020-03-30"
}



### XXX
GET http://localhost:8080/dt/order3?createTime=2020-03-30 09:44:58&createDate=2020-03-30
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

<> 2020-03-30T101452.200.json


### XXX
POST http://localhost:8080/dt/order2?createTime=2020-03-30 09:44:58&createDate=2020-03-30
Accept: */*
Cache-Control: no-cache
Content-Type: application/json

{
  "createTime": "2020-03-30 09:44:58",
  "createDate": "2020-03-30"
}

輸出:<> 2020-03-30T102822.200.json
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8
Date: Mon, 30 Mar 2020 02:28:22 GMT

{
  "createTime": "2020-03-30 10:28:22",
  "createDate": "2020-03-30"
}


5 文章源碼
springboot2-jdk8-LocalDate

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市脐瑰,隨后出現(xiàn)的幾起案子工禾,更是在濱河造成了極大的恐慌,老刑警劉巖鳍寂,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件改含,死亡現(xiàn)場離奇詭異,居然都是意外死亡迄汛,警方通過查閱死者的電腦和手機(jī)捍壤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門骤视,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹃觉,你說我怎么就攤上這事专酗。” “怎么了盗扇?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵笼裳,是天一觀的道長。 經(jīng)常有香客問我粱玲,道長躬柬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任抽减,我火速辦了婚禮允青,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘卵沉。我一直安慰自己颠锉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布史汗。 她就那樣靜靜地躺著琼掠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪停撞。 梳的紋絲不亂的頭發(fā)上瓷蛙,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音戈毒,去河邊找鬼艰猬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛埋市,可吹牛的內(nèi)容都是我干的冠桃。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼道宅,長吁一口氣:“原來是場噩夢啊……” “哼食听!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起污茵,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤樱报,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后省咨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肃弟,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笤受。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穷缤。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖箩兽,靈堂內(nèi)的尸體忽然破棺而出津肛,到底是詐尸還是另有隱情,我是刑警寧澤汗贫,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布身坐,位于F島的核電站,受9級(jí)特大地震影響落包,放射性物質(zhì)發(fā)生泄漏部蛇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一咐蝇、第九天 我趴在偏房一處隱蔽的房頂上張望涯鲁。 院中可真熱鬧,春花似錦有序、人聲如沸抹腿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孕锄。三九已至旋膳,卻和暖如春专执,著一層夾襖步出監(jiān)牢的瞬間飞几,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工微渠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搭幻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓逞盆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親松申。 傳聞我的和親對(duì)象是個(gè)殘疾皇子云芦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容