自定义日期转换配置
文章目录
- 1.日期问题出现原因以及解决方案概述
- 1.图示
- 2.三种解决方案概述
- 1.对于表单数据 application/x-www-form-urlencoded
- 2.对于JSON数据
- 1.使用@JsonFormat注解
- 2.自定义Jackson日期转换配置
- 2.解决方案
- common-web-starter
- 1.目录
- 2.BaseController.java 使用@InitBinder解决表单数据的日期转换问题
- 3.JacksonConfig.java 自定义Jackson日期转换配置
- 4.DateUtils.java 日期转换工具类
- 5.WebAutoConfiguration.java 导入JacksonConfig配置类
- 6.spring.factories 指定自动配置类
1.日期问题出现原因以及解决方案概述
1.图示
2.三种解决方案概述
1.对于表单数据 application/x-www-form-urlencoded
使用@InitBinder将日期JSON字符串转化为Java中的Date对象
2.对于JSON数据
1.使用@JsonFormat注解
使用@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)注解指定反序列化和序列化的格式
2.自定义Jackson日期转换配置
2.解决方案
common-web-starter
1.目录
2.BaseController.java 使用@InitBinder解决表单数据的日期转换问题
package com.sunxiansheng.web.base;import com.sunxiansheng.web.response.RespBeanEnum;
import com.sunxiansheng.web.response.Result;
import com.sunxiansheng.web.utils.DateUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;import java.beans.PropertyEditorSupport;
import java.util.Date;/*** Description: Controller层基类** @Author sun* @Create 2024/10/26 09:48* @Version 1.0*/
public class BaseController {/*** 将前台传递过来的日期格式的字符串,自动转化为Date类型* 注意:只对表单参数(application/x-www-form-urlencoded)或查询参数生效,对于json格式的请求不生效*/@InitBinderpublic void initBinder(WebDataBinder binder) {// Date 类型转换binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {@Overridepublic void setAsText(String text) {setValue(DateUtils.parseDate(text));}});}/*** 成功** @return*/public Result<Object> ok() {return Result.ok();}/*** 失败** @return*/public Result<Object> fail() {return Result.fail();}/*** 失败,自定义消息** @param message* @return*/public Result<Object> fail(String message) {return Result.fail(message);}/*** 失败,自定义状态码和消息** @param code* @param message* @return*/public Result<Object> fail(int code, String message) {return Result.fail(code, message);}/*** 失败,自定义枚举** @param respBeanEnum* @return*/public Result<Object> fail(RespBeanEnum respBeanEnum) {return Result.fail(respBeanEnum);}
}
3.JacksonConfig.java 自定义Jackson日期转换配置
package com.sunxiansheng.web.config;import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
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.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;/*** 自定义日期转换配置:优先级总结* <p>* 1. @JsonFormat 注解:最高优先级。* 2. 自定义序列化和反序列化器:优先于全局配置,但在检测到 @JsonFormat 时会让位于注解逻辑。* 3. jacksonObjectMapperBuilder.simpleDateFormat():默认全局配置,优先级最低。** @author sunxiansheng*/
@Configuration
@ConditionalOnClass(com.fasterxml.jackson.databind.ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfig {@Beanpublic Jackson2ObjectMapperBuilderCustomizer customizer() {return jacksonObjectMapperBuilder -> {// 设置地区为中国,确保格式符合中文区域习惯jacksonObjectMapperBuilder.locale(Locale.CHINA);// 设置时区为系统默认时区,避免时区偏差jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));/*** • 全局设置默认的日期格式,作用于 Date 类型的字段(不包括 LocalDate、LocalDateTime 等 Java 8 时间类)。* • 只影响 Jackson 自动序列化和反序列化时的默认行为。* • 如果在实体类的字段上没有使用 @JsonFormat 注解,Jackson 会采用这里设置的格式。*/jacksonObjectMapperBuilder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");// 注册自定义 JavaTimeModule 模块,处理 Java 8 日期时间类型和 Date 类型jacksonObjectMapperBuilder.modules(new JavaTimeModule());};}/*** JavaTimeModule 是一个自定义的 Jackson 模块,用于序列化和反序列化 Java 8 日期时间类型。* • 覆盖默认的 Jackson 序列化和反序列化行为,为 Date 类型字段提供自定义逻辑。* • 允许支持多个格式的反序列化,例如通过自定义的 CustomDateDeserializer。*/public static class JavaTimeModule extends SimpleModule {public JavaTimeModule() {// 添加 LocalDateTime 类型的序列化和反序列化器,确保格式为 "yyyy-MM-dd HH:mm:ss"this.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));this.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));// 添加 LocalDate 类型的序列化和反序列化器,确保格式为 "yyyy-MM-dd"this.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));this.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));// 添加 LocalTime 类型的序列化和反序列化器,确保格式为 "HH:mm:ss"this.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));this.addDeserializer(LocalTime.class,new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));// 添加对 Date 类型的自定义序列化和反序列化,这里会覆盖上面默认的Date序列化器配置this.addSerializer(Date.class,new com.fasterxml.jackson.databind.ser.std.DateSerializer(false, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));this.addDeserializer(Date.class, new CustomDateDeserializer());}}/*** 自定义的 Date 反序列化器,支持多种格式的日期字符串解析。*/public static class CustomDateDeserializer extends JsonDeserializer<Date> {// 定义支持的日期格式列表private static final List<String> DATE_PATTERNS = Arrays.asList("yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM","yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM","yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM");@Overridepublic Date deserialize(JsonParser p, com.fasterxml.jackson.databind.DeserializationContext ctxt)throws IOException, JsonProcessingException {String dateStr = p.getText().trim();for (String pattern : DATE_PATTERNS) {try {// 尝试使用每个格式进行解析return new SimpleDateFormat(pattern).parse(dateStr);} catch (ParseException e) {// 如果解析失败,继续尝试下一个格式}}// 如果所有格式都不匹配,抛出异常throw new IOException("Invalid date format: " + dateStr);}}
}
4.DateUtils.java 日期转换工具类
package com.sunxiansheng.web.utils;import org.apache.commons.lang3.time.DateFormatUtils;import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;/*** 时间工具类*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {public static String YYYY = "yyyy";public static String YYYY_MM = "yyyy-MM";public static String YYYY_MM_DD = "yyyy-MM-dd";public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM","yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM","yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};/*** 获取当前Date型日期** @return Date() 当前日期*/public static Date getNowDate() {return new Date();}/*** 获取当前日期, 默认格式为yyyy-MM-dd** @return String*/public static String getDate() {return dateTimeNow(YYYY_MM_DD);}public static final String getTime() {return dateTimeNow(YYYY_MM_DD_HH_MM_SS);}public static final String dateTimeNow() {return dateTimeNow(YYYYMMDDHHMMSS);}public static final String dateTimeNow(final String format) {return parseDateToStr(format, new Date());}public static final String dateTime(final Date date) {return parseDateToStr(YYYY_MM_DD, date);}public static final String parseDateToStr(final String format, final Date date) {return new SimpleDateFormat(format).format(date);}public static final Date dateTime(final String format, final String ts) {try {return new SimpleDateFormat(format).parse(ts);} catch (ParseException e) {throw new RuntimeException(e);}}/*** 日期路径 即年/月/日 如2018/08/08*/public static final String datePath() {Date now = new Date();return DateFormatUtils.format(now, "yyyy/MM/dd");}/*** 日期路径 即年/月/日 如20180808*/public static final String dateTime() {Date now = new Date();return DateFormatUtils.format(now, "yyyyMMdd");}/*** 日期型字符串转化为日期 格式*/public static Date parseDate(Object str) {if (str == null) {return null;}try {return parseDate(str.toString(), parsePatterns);} catch (ParseException e) {return null;}}/*** 获取服务器启动时间*/public static Date getServerStartDate() {long time = ManagementFactory.getRuntimeMXBean().getStartTime();return new Date(time);}/*** 计算相差天数*/public static int differentDaysByMillisecond(Date date1, Date date2) {return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));}/*** 计算时间差** @param endDate 最后时间* @param startTime 开始时间* @return 时间差(天/小时/分钟)*/public static String timeDistance(Date endDate, Date startTime) {long nd = 1000 * 24 * 60 * 60;long nh = 1000 * 60 * 60;long nm = 1000 * 60;// long ns = 1000;// 获得两个时间的毫秒时间差异long diff = endDate.getTime() - startTime.getTime();// 计算差多少天long day = diff / nd;// 计算差多少小时long hour = diff % nd / nh;// 计算差多少分钟long min = diff % nd % nh / nm;// 计算差多少秒//输出结果// long sec = diff % nd % nh % nm / ns;return day + "天" + hour + "小时" + min + "分钟";}/*** 增加 LocalDateTime ==> Date*/public static Date toDate(LocalDateTime temporalAccessor) {ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());return Date.from(zdt.toInstant());}/*** 增加 LocalDate ==> Date*/public static Date toDate(LocalDate temporalAccessor) {LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());return Date.from(zdt.toInstant());}
}
5.WebAutoConfiguration.java 导入JacksonConfig配置类
6.spring.factories 指定自动配置类
相关文章:

自定义日期转换配置
文章目录 1.日期问题出现原因以及解决方案概述1.图示2.三种解决方案概述1.对于表单数据 application/x-www-form-urlencoded2.对于JSON数据1.使用JsonFormat注解2.自定义Jackson日期转换配置 2.解决方案common-web-starter1.目录2.BaseController.java 使用InitBinder解决表单数…...

“AI智能服务平台系统,让生活更便捷、更智能
大家好,我是资深产品经理老王,今天咱们来聊聊一个让生活变得越来越方便的高科技产品——AI智能服务平台系统。这个系统可是现代服务业的一颗璀璨明珠,它究竟有哪些魅力呢?下面我就跟大家伙儿闲聊一下。 一、什么是AI智能服务平台系…...

SQL美化器优化
文章目录 1.目录2.代码 1.目录 2.代码 package com.sunxiansheng.mybatis.plus.inteceptor;import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.*; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.*…...

我的128天创作之路:回顾与展望
大家好呀!今天来和你们分享一下我的创作历程😁。 一、机缘 最开始创作呢,是因为在学习 C 的 STL 时,像 string、list、vector 这些模板可把我折腾得够呛,但也让我学到了超多东西!我就想,要是把我…...

内核配置参数整理
#参考网页 linux5.2 <.config>文件注释 详细解释 CONFIG_ARMy:启用ARM架构支持,这是ARM处理器专用的内核配置选项。 CONFIG_ARM_HAS_SG_CHAINy:启用对散列表(scatter-gather)链的支持…...

SpringBoot整合Easy-es
一.什么是Easy-Es Easy-Es(简称EE)是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架,在 RestHighLevelClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称…...

于交错的路径间:分支结构与逻辑判断的思维协奏
大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。* 这一节内容很多,文章字数达到了史无前例的一万一,我们要来学习分支与循环结构中…...

Linux之读者写者模型与特殊锁的学习
目录 读者写者模型 特殊锁 悲观锁 自旋锁 在前几期,我们学习了多线程的生产者和消费者模型,生产者和消费者模型中,有三种关系,两个角色,一个场所,那么读者写者模型和生产者消费者模型有什么关联吗&…...

回溯专题 记录
回溯的题目按照这套模板进行; 我感觉整体逻辑还是递归,只不过有了pop_back才是回溯概念; class Solution {public:vector<int> path;vector<vector<int>> ans;void backtracking(int n,int k,int startindex){if(path.…...

使用 Python 实现自动化办公(邮件、Excel)
目录 一、Python 自动化办公的准备工作 1.1 安装必要的库 1.2 设置邮件服务 二、邮件自动化处理 2.1 发送邮件 示例代码 注意事项 2.2 接收和读取邮件 示例代码 三、Excel 自动化处理 3.1 读取和写入 Excel 文件 示例代码 3.2 数据处理和分析 示例代码 四、综合…...

贪心算法笔记
贪心算法笔记 大概内容 贪心就是对于一个问题有很多个步骤,我们在每一个步骤中都选取最优的那一个,最后得出答案。就是在一些函数中可行,但是有些比如二次函数,因为它的转折点不一定最优,就是不可行的。那么如何判断贪心呢?有这么几种 看时间复杂度,一般的就是 O ( n…...

Formality:两种等价状态consistency和equality
相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 背景 逻辑锥的等价性检查时,存在两种验证模式:一致(consistency)和等同(equality),要理解这两点,首先得明白综合工具…...

Java Web开发基础:HTML的深度解析与应用
文章目录 前言🌍一.B/S 软件开发架构简述🌍二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 🌍三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…...

第30章 汇编语言--- 性能优化技巧
汇编语言是用于直接编程计算机硬件的低级语言,它几乎是一对一地映射到机器指令。因为汇编代码与特定处理器架构紧密相关,所以在讨论性能优化技巧时,通常需要考虑具体的CPU架构和指令集。 以下是一些通用的汇编语言性能优化技巧,并…...

HTB:Paper[WriteUP]
目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 对靶机进行子域…...

数据库中的 DDL、DML 和 DCL
数据库中的 DDL、DML 和 DCL 在数据库的定义与操作中,DDL、DML 和 DCL 是三个核心概念,分别用于不同层面的数据库管理与操作。 1. DDL(Data Definition Language) - 数据定义语言 定义 DDL 用于定义和管理数据库的结构或模式。…...

OKR 极简史及理解
大家读完觉得有帮助记得点赞和关注!!! 目录 MBO SMART 和 KPI OKR 1. 什么是 OKR? 1.1 Objectives(目标) 1.2 Key Results(关键成果) KR 应当是困难的,但并非不可…...

电商项目-基于ElasticSearch实现商品搜索功能(四)
一、 高亮显示 1.1 高亮分析 高亮显示是指根据商品关键字搜索商品的时候,显示的页面对关键字给定了特殊样式,让它显示更加突出,如商品搜索中,关键字变成了红色,其实就是给定了红色样式。 1.2 高亮搜索实现步骤解析 …...

TCP封装数据帧
void *send_data(void *arg) //这是一个发送数据的线程 {int sockfd init_tcp_cli("192.168.0.148",50000) //传ip和port,port 50000是因为大概前五万都被其它服务所占用,50000后是私人ipif(sockfd < 0){return NULL;}unsigned char …...

数据结构与算法之二叉树: LeetCode 515. 在每个树行中找最大值 (Ts版)
在每个树行中找最大值 https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/ 描述 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值 示例1 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9]示例2 输入: root [1,2,3]…...

百度视频搜索架构演进
导读 随着信息技术的迅猛发展,搜索引擎作为人们获取信息的主要途径,其背后的技术架构也在不断演进。本文详细阐述了近年来视频搜索排序框架的重大变革,特别是在大模型技术需求驱动下,如何从传统的多阶段级联框架逐步演变为更加高…...

构造函数的原型原型链
代码示例 // 定义一个构造函数 Test function Test() {this.name 张三 }; //向构造函数的原型添加一个属性 age18 Test.prototype.age 18;//使用构造函数 Test 来实例化一个新对象 const test new Test();//向 Object.prototype 添加了一个名为 sex 的属性,其值…...

nginx反向代理及负载均衡
华子目录 nginx反向代理功能http反向代理反向代理配置参数proxy_pass的注意事项案例:反向代理单台后端服务器案例:反向代理实现动静分离案例:反向代理的缓存功能非缓存场景下测压准备缓存缓存场景下测压验证缓存文件 反向代理负载均衡&#x…...

单片机实物成品-011 火灾监测
火灾监测(20个版本) 版本20: oled显示温湿度烟雾浓度火焰传感器天然气浓度窗户风扇水泵排气系统声光报警语音播报按键WIFI模块 ----------------------------------------------------------------------------- https://www.bilibili.com…...

使用 Docker 在 Alpine Linux 下部署 Caddy 服务器
简介 在现代 web 开发中,选择合适的 web 服务器至关重要。Caddy 是一个功能强大的现代化 HTTP/2 服务器,支持自动 HTTPS,配置简单,适合开发和生产环境。Docker 则为我们提供了一种轻量级的容器化技术,使得应用程序的部…...

每日十题八股-2025年1月12日
1.为什么四次挥手之后要等2MSL? 2.服务端出现大量的timewait有哪些原因? 3.TCP和UDP区别是什么? 4.TCP为什么可靠传输 5.怎么用udp实现http? 6.tcp粘包怎么解决? 7.TCP的拥塞控制介绍一下? 8.描述一下打开百度首页后发生的网络过…...

Python中定位包含特定文本信息的元素
目录 一、为什么需要定位包含文本信息的元素 二、使用Selenium定位包含文本的元素 1. 使用find_element_by_link_text 2. 使用find_element_by_partial_link_text 3. 使用XPath定位包含文本的元素 4. 使用CSS选择器定位包含文本的元素 三、使用BeautifulSoup定位包含文本…...

uniapp实现H5页面内容居中与两边留白,打造类似微信公众号阅读体验
在 UniApp 中,由于需要兼容多端应用,我们通常使用 rpx 作为尺寸单位。然而,在某些情况下,如需要实现内容居中且两边留白时,直接使用 rpx 可能会带来一些限制。这时,我们可以考虑使用 px 或 rem 等单位&…...

极品飞车6里的赛道简介
极品飞车里有很多赛道,赛道分为前向赛道Forward、后向赛道Backward。前向赛道Forward是从A点到B点;后向赛道Backward是前向赛道的逆过程,即从B点到A点。这里介绍极品飞车6的赛道长度、中英文名称翻译、难度等级。 序号赛道英文名赛道中文名总长(km)急弯难度等级1Alpine Trai…...

SAP推出云端ERP解决方案,加速零售行业数字化转型
2025年1月9日,SAP发布了一款专为零售行业设计的云端ERP行业解决方案——S/4HANA Cloud Public Edition,进一步推动企业向云端迁移。这款解决方案旨在集中运营数据,整合财务、采购和商品管理流程,以帮助零售企业优化运营效率。 核…...