现在忙于学习算法、网络。待今年下半年,将Spring格式转换器从源码层面梳理一遍,届时大家就会明白Spring从PropertiesEditor、Convert、Format的转换机制了

效果

@Autowired
private ConversionService conversionService;@Test
void contextLoads() {// 2021-03-07 14:47:57String localDateTime = conversionService.convert(LocalDateTime.now(), String.class);// 2021-03-07String localDate = conversionService.convert(LocalDate.now(), String.class);// 14:47:57String localTime = conversionService.convert(LocalTime.now(), String.class);// 2021-03-07T14:47:57LocalDateTime localDateTime1 = conversionService.convert(localDateTime, LocalDateTime.class);// 2021-03-07LocalDate localDate1 = conversionService.convert(localDate, LocalDate.class);// 14:47:57LocalTime localTime1 = conversionService.convert(localTime, LocalTime.class);
}

由于SpringMVC中,注解PathVariable、RequestParam注解所使用的转换器为Convert之类,所以前后端交互时,前端按照指定格式转给后端,后端可以直接按照LocalDate/LocalTime/LocalDateTime类型来接收。而在RequestBody中,默认会按照Jackson来解析,后面在分享完Jackson源码后,会分析怎样通过将orderCode直接转换为OrderDO对象(即在封装在Controller方法入参时,其会发送一个SQL通过orderCode获取到其OrderDO对象,并封装到方法入参中)

实现

配置

# WebMvcProperties.Format 配置format实体类属性
spring.mvc.format.time=HH:mm:ss
spring.mvc.format.date=yyyy-MM-dd
spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss

起效

// WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcConversionService
// FormattingConversionService实现了ConversionService接口
@Bean
@Override
public FormattingConversionService mvcConversionService() {// 获取上面的属性对象Format format = this.mvcProperties.getFormat();// WebConversionService是Spring定义的一个自动类型转换器// 此构造器为关键WebConversionService conversionService = new WebConversionService(new DateTimeFormatters().dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));addFormatters(conversionService);return conversionService;
}
public WebConversionService(DateTimeFormatters dateTimeFormatters) {super(false);// 因为存在自定义if (dateTimeFormatters.isCustomized()) {addFormatters(dateTimeFormatters);} else {addDefaultFormatters(this);}
}
// 最终随着调用链会registerFormatters,register Format ter s 可以理解为 注册格式化器
public void registerFormatters(FormatterRegistry registry) {DateTimeConverters.registerConverters(registry);DateTimeFormatter df = getFormatter(Type.DATE);DateTimeFormatter tf = getFormatter(Type.TIME);DateTimeFormatter dtf = getFormatter(Type.DATE_TIME);// Efficient ISO_LOCAL_* variants for printing since they are twice as fast...registry.addFormatterForFieldType(LocalDate.class,new TemporalAccessorPrinter(df == DateTimeFormatter.ISO_DATE ? DateTimeFormatter.ISO_LOCAL_DATE : df),new TemporalAccessorParser(LocalDate.class, df));registry.addFormatterForFieldType(LocalTime.class,new TemporalAccessorPrinter(tf == DateTimeFormatter.ISO_TIME ? DateTimeFormatter.ISO_LOCAL_TIME : tf),new TemporalAccessorParser(LocalTime.class, tf));registry.addFormatterForFieldType(LocalDateTime.class,new TemporalAccessorPrinter(dtf == DateTimeFormatter.ISO_DATE_TIME ? DateTimeFormatter.ISO_LOCAL_DATE_TIME : dtf),new TemporalAccessorParser(LocalDateTime.class, dtf));registry.addFormatterForFieldType(ZonedDateTime.class,new TemporalAccessorPrinter(dtf),new TemporalAccessorParser(ZonedDateTime.class, dtf));registry.addFormatterForFieldType(OffsetDateTime.class,new TemporalAccessorPrinter(dtf),new TemporalAccessorParser(OffsetDateTime.class, dtf));registry.addFormatterForFieldType(OffsetTime.class,new TemporalAccessorPrinter(tf),new TemporalAccessorParser(OffsetTime.class, tf));registry.addFormatterForFieldType(Instant.class, new InstantFormatter());registry.addFormatterForFieldType(Period.class, new PeriodFormatter());registry.addFormatterForFieldType(Duration.class, new DurationFormatter());registry.addFormatterForFieldType(Year.class, new YearFormatter());registry.addFormatterForFieldType(Month.class, new MonthFormatter());registry.addFormatterForFieldType(YearMonth.class, new YearMonthFormatter());registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter());registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
}

在看看formatter的定义

// org.springframework.format.Formatter
public interface Formatter<T> extends Printer<T>, Parser<T> {}
public interface Printer<T> {// 将对象根据指定Locale指定转化器转换为StringString print(T object, Locale locale);
}
public interface Parser<T> {// 将String 按照指定Locale解析为ObjectT parse(String text, Locale locale) throws ParseException;
}

Java8 时间转换器相关推荐

  1. java joda datetime_Joda Time项目和java8时间api

    Joda Time出现的背景 在java1.0中,对日期和时间的支持只能依赖java.util.Date类.正如类名所表达的,这个类无法表示日期,只能以毫秒的精度表示时间.更糟糕的是它的易用性,由于某 ...

  2. java8 joda_Joda Time项目和java8时间api

    Joda Time出现的背景 在java1.0中,对日期和时间的支持只能依赖java.util.Date类.正如类名所表达的,这个类无法表示日期,只能以毫秒的精度表示时间.更糟糕的是它的易用性,由于某 ...

  3. android 时间转换 工具下载,时间转换器手游下载_时间转换器安卓版下载v1.09.25_3DM手游...

    <时间转换器>是一款益智却不是很难的休闲手游,游戏通过一种时空转换器[小蓝方块]将过去的自己召唤出来,沿着过去的轨迹行走,这类似于人生,人生也是在不断回首过去的时候在不断向前进,回首过去, ...

  4. java8 时间加一秒_Java8中对时间的处理

    Java8中对时间的处理主要是LocalDate.LocalTime.LocalDateTime这几个类实现,直接看下面的测试代码,注释很详细. @ java8时间处理测试 /** * java8时间 ...

  5. springboot 全局时间转换器

    目录结构 前言 前端操作 Network Headers Network preview 后台日志信息 问题所在 解决办法一 解决办法二 参考链接 前言 前端框架:layui mini 后台框架:sp ...

  6. java8 时间类API

    前言 Instant LocalDate Clock SystemnanoTime 前言 (未完待续) 推荐一篇系统学习的java8时间类文章 我这里会介绍java8 新API中常用个类怎么用 应该是 ...

  7. 如Java8的LocalDate与Date相互转换、ZonedDateTime等常用操作包含多个使用示例、Java8时区ZoneId的使用方法、Java8时间字符串解析成类

    下面将依次介绍 Date转Java8时间类操作 ,Java8时间类LocalDate常用操作(如获得当前日期,两个日期相差多少天,下个星期的日期,下个月第一天等) 解析不同时间字符串成对应的Java8 ...

  8. Java8时间校正器

    TemporalAdjuster:时间校正器. TemporalAdjusters:该类通过静态方法提供了大量的常用TemporalAdjuster的实现. package com.expgiga.J ...

  9. 表单时间转换器(formatDate)

    //表单时间转换器 formatDate(date, fmt) {let time = {'M+': date.getMonth() + 1, // 月份'd+': date.getDate(), / ...

最新文章

  1. Linux系统版 lscpu
  2. linux运维常用命令一句话(持续更新中)
  3. M2 Scrum 12.08
  4. 漫说单例模式--宝宝成长记 你真的了解了吗?
  5. Python探索记(01)——HelloWorld及Python的注释
  6. 安卓应用安全指南 4.1.3 创建/使用活动 高级话题
  7. iOS学习笔记-自定义过渡动画
  8. 关于EPOLL的ET和LT模式的深入理解
  9. 【关于测试开发工程师】
  10. 数据哪里找?200个源数据网站全给你!
  11. 【luogu 3868】中国剩余定理模板题
  12. 野火 步进电机 视频笔记
  13. 摄像模组中光学相关知识(三)
  14. Node-Red系列教程——NodeRed使用node-red-node-email组件发送QQ邮件
  15. 【历史上的今天】1 月 8 日:谷歌推出 Google Pay;Quibi 的重生;平衡二叉树的发明者出生
  16. 用Cocos2d-JS制作一个类神经猫游戏《你是我的小羊驼》
  17. android studio开发下落四子棋
  18. 全文指引:《大道至易》中附录摘引的全文目录
  19. leap motion原理
  20. 如何用python画长方形_Python如何绘制长方形

热门文章

  1. python中的随机函数random的用法示例
  2. Zookeeper 分布式锁
  3. GIS时空大数据融合技术——美丽长岛数据融合
  4. Splinter入门(一)splinter安装与使用
  5. APS5840 DC-DC升降压恒流驱动IC 高效率 电流精度3%
  6. java中Unsafe使用讲解
  7. 机器学习100天(二十):020 分类模型评价指标-PR曲线
  8. 蓝牙耳机纯知识科普:想要音质好,在选购中一定注意这个问题!
  9. uniapp的html中文乱码
  10. 《早晨从中午开始》读书笔记