没想到!springboot 可以这样做全局日期格式化,有点香!

说在前边

最近部门几位同事受了一些委屈相继离职,共事三年临别之际颇有不舍,待一切手续办妥帖,寒暄过后送他们出公司,几个老哥临别时冲我鬼魅一笑,我顿时心里一紧有种不好的预感,这事绝对没有这么简单。等我接手这几个大佬的项目后,应验了我的预感,此刻我居然有点后悔,为啥送别之时没揍他们一顿!哈哈哈~ 而这种打人的冲动,在我开始优化几位老哥的项目时候,变得越来越强烈。

没想到!springboot 可以这样做全局日期格式化,有点香!

有个坑

技术部每个月都会组织一下代码走查及优化,以前是各自审查优化自己的项目,如今几位老哥的离职他们的项目就落到了我的头上。对于程序员来说最痛苦的事情就是接手别人的项目,还要做优化改造,因为这一点也不比重构一遍项目简单。不过,军令在前,没办法硬着头皮上吧!

第一个优化的点就让我有点崩溃,这几个大佬的技能能力很强,一直都是我学习的榜样,但在项目里几乎所有的日期格式化都这样用 SimpleDateFormat ,像如下代码这样实现,emm~ ,受过伤的男人怎么啥事都做的出来,哈哈哈~

<code>

1

SvcOrderDailyStatisticsPo orderDailyStatisticsPo = 

new

 SvcOrderDailyStatisticsPo();

2

SimpleDateFormat dateFormat = 

new

 SimpleDateFormat(

"yyyy-MM-dd"

);

3

Date

 stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));

4

orderDailyStatisticsPo.setStatisticalDate(stationTime);/<code>

而且项目中的时间和日期API用的也比较混乱,考虑到 java.util.Date 和 java.util.Calendar 不支持时区,且非线程安全,对于日期的计算相对繁琐,技术部一致要求用JDK1.8以后的 java.time LocalDateTime。但不少人还是在用 java.util.Date 和 java.util.Calendar 处理日期。

优化方案

时间格式化是使用频率非常高的,如何让时间格式化变得既简单又不用重复造轮子,那么就应将它抽象出来,作为全局的日期格式化处理,下面就结合实践简单介绍下几种优化方案。

测试地址:http://127.0.0.1:8080/timeTest

<code>

1

(

"/timeTest"

)

2

    

public

 OrderInfo 

timeTest

()

 

{

3

        OrderInfo order = 

new

 OrderInfo();

4

        order.setCreateTime(LocalDateTime.now());

5

        order.setUpdateTime(

new

 Date());

6

        

return

 order;

7

    }/<code>

1、@JsonFormat注解

使用@JsonFormat注解格式化时间,应该算是一个基本操作了,大部分开发者都应用此种方式,简单方便。

<code> 

1

5

public

 

class

 

OrderInfo

 

{

6

7

     (locale = 

"zh"

, timezone = 

"GMT+8"

, pattern = 

"yyyy-MM-dd HH:mm:ss"

)

8

    

private

 LocalDateTime createTime;

9

10

     (locale = 

"zh"

, timezone = 

"GMT+8"

, pattern = 

"yyyy-MM-dd HH:mm:ss"

)

11

    

private

 Date updateTime;

12

13

    

public

 LocalDateTime 

getCreateTime

()

 

{

14

        

return

 createTime;

15

    }

16

17

    

public

 

void

 

setCreateTime

(LocalDateTime createTime)

 

{

18

        

this

.createTime = createTime;

19

    }

20

21

    

public

 Date 

getUpdateTime

()

 

{

22

        

return

 updateTime;

23

    }

24

25

    

public

 

void

 

setUpdateTime

(Date updateTime)

 

{

26

        

this

.updateTime = updateTime;

27

    }

28

}/<code>

测试一下结果,发现 Date 类型和 LocalDateTime 类型都格式化成功,但还是有个问题,这样做仍然比较繁琐,每个实体类的日期字段都要加@JsonFormat注解,重复的工作量也不小。接着往下看~

没想到!springboot 可以这样做全局日期格式化,有点香!

2、全局配置 (1)

Springboot 已经为我们提供了日期格式化 ${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss},这里我们需要进行全局配置,配置比较简单,也无需在实体类属性上添加@JsonFormat注解。

<code> 

1

/**

2

 

*

 

@Author:

 

xiaofu

3

 

*

 

@Description:

4

 

*/

5public

 

class

 

OrderInfo

 

{

6

7

    

//@JsonFormat(locale

 

=

 

"zh"

,

 

timezone

 

=

 

"GMT+8"

,

 

pattern

 

=

 

"yyyy-MM-dd HH:mm:ss"

)

8

    

private

 

LocalDateTime

 

createTime;

9

10

    

//@JsonFormat(locale

 

=

 

"zh"

,

 

timezone

 

=

 

"GMT+8"

,

 

pattern

 

=

 

"yyyy-MM-dd HH:mm:ss"

)

11

    

private

 

Date

 

updateTime;

12

13

    

public

 

LocalDateTime

 

getCreateTime()

 

{

14

        

return

 

createTime;

15

    

}

16

17

    

public

 

void

 

setCreateTime(LocalDateTime

 

createTime)

 

{

18

        

this.createTime

 

=

 

createTime;

19

    

}

20

21

    

public

 

Date

 

getUpdateTime()

 

{

22

        

return

 

updateTime;

23

    

}

24

25

    

public

 

void

 

setUpdateTime(Date

 

updateTime)

 

{

26

        

this.updateTime

 

=

 

updateTime;

27

    

}

28

}

/<code>

只需要用@Configuration定义一个配置类,注入两个Bean即可完成全局日期格式化处理,这种方式也是当前我项目中正在用的方式。

<code> 

1

5

6

public

 

class

 

LocalDateTimeSerializerConfig

 

{

7

8

    

9

    

private

 String pattern;

10

11

    

12

    

public

 LocalDateTimeSerializer localDateTimeDeserializer() {

13

        

return

 new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));

14

    }

15

16

    

17

    

public

 Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

18

        

return

 builder -> builder.serializerByType(LocalDateTime

.

class

localDateTimeDeserializer

());

19

    }

20

}/<code>

这种方式可支持 Date 类型和 LocalDateTime 类型并存,那么有一个问题就是现在全局时间格式是yyyy-MM-dd HH:mm:ss,但有的字段却需要yyyy-MM-dd格式咋整?

那就需要配合@JsonFormat注解使用,在特定的字段属性添加@JsonFormat注解即可,因为@JsonFormat注解优先级比较高,会以@JsonFormat注解标注的时间格式为主。

3、全局配置 (2)

这种全局配置的实现方式与上边的效果是一样的,不过,要注意的是使用这种配置后,字段手动配置@JsonFormat注解将不再生效。

<code> 

1

/**

2

 

*

 

@Author:

 

xiaofu

3

 

*

 

@Description:

4

 

*/

5public

 

class

 

OrderInfo

 

{

6

7

    

//@JsonFormat(locale

 

=

 

"zh"

,

 

timezone

 

=

 

"GMT+8"

,

 

pattern

 

=

 

"yyyy-MM-dd HH:mm:ss"

)

8

    

private

 

LocalDateTime

 

createTime;

9

10

    

//@JsonFormat(locale

 

=

 

"zh"

,

 

timezone

 

=

 

"GMT+8"

,

 

pattern

 

=

 

"yyyy-MM-dd HH:mm:ss"

)

11

    

private

 

Date

 

updateTime;

12

13

    

public

 

LocalDateTime

 

getCreateTime()

 

{

14

        

return

 

createTime;

15

    

}

16

17

    

public

 

void

 

setCreateTime(LocalDateTime

 

createTime)

 

{

18

        

this.createTime

 

=

 

createTime;

19

    

}

20

21

    

public

 

Date

 

getUpdateTime()

 

{

22

        

return

 

updateTime;

23

    

}

24

25

    

public

 

void

 

setUpdateTime(Date

 

updateTime)

 

{

26

        

this.updateTime

 

=

 

updateTime;

27

    

}

28

}

/<code>
<code> 

1

5

6

public

 

class

 

LocalDateTimeSerializerConfig

 

{

7

8

     (

"${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}"

)

9

    

private

 String pattern;

10

11

    

12

    

13

    

public

 ObjectMapper 

serializingObjectMapper

()

 

{

14

        ObjectMapper objectMapper = 

new

 ObjectMapper();

15

        JavaTimeModule javaTimeModule = 

new

 JavaTimeModule();

16

        javaTimeModule.addSerializer(LocalDateTime

.

class

new

 

LocalDateTimeSerializer

())

;

17

        javaTimeModule.addDeserializer(LocalDateTime

.

class

new

 

LocalDateTimeDeserializer

())

;

18

        objectMapper.registerModule(javaTimeModule);

19

        

return

 objectMapper;

20

    }

21

22

    

public

 

class

 

LocalDateTimeSerializer

 

extends

 

JsonSerializer

<

LocalDateTime

{

23

        

24

        

public

 

void

 

serialize

(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)

 

throws

 IOException 

{

25

            gen.writeString(value.format(ofPattern(pattern)));

26

        }

27

    }

28

29

    

public

 

class

 

LocalDateTimeDeserializer

 

extends

 

JsonDeserializer

<

LocalDateTime

{

30

        

31

        

public

 LocalDateTime 

deserialize

(JsonParser p, DeserializationContext deserializationContext)

 

throws

 IOException 

{

32

            

return

 LocalDateTime.parse(p.getValueAsString(), ofPattern(pattern));

33

        }

34

    }

35

}/<code>

总结

分享了一个Springboot项目开发过程中的一个小技巧,也顺便吐槽一下项目优化中遇到的坑,优化别的人的代码虽然是一件比较痛苦的事情,但在这个过程中确实能学习到很多技巧,对个人的技能提升也是很有帮助,因为都是些能够实实在在提高开发效率的干货。

感悟

从正式成为一名程序员的那天起,注定要进行没有止境的学习,想要进阶高级或者专家,就要坚持每天都高效的学习,不要给自己的懒惰找借口,“什么我也想学习可是又没有资源”,这次我给你整理好了,我看你还有啥理由!私信回复【666】送你

没想到!springboot 可以这样做全局日期格式化,有点香!


分享到:


相關文章: