spring boot 与 jdk8 LocalDate LocalDateTime集成

[TOC]

spring boot 与 jdk8 LocalDate LocalDateTime集成

  1. pom.xml
    重点是 加入依赖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增强序列化生成器
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 不可优化使用Lambda表达式,否则会出现启动失败的问题 
 * @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序列化和反序列化转换器,用于转换Post请求体中的json以及将我们的对象序列化为返回响应的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,我们在这里修改了日期格式
//        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 输出结果
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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容