日期格式统一处理

devtools/2024/10/19 6:28:31/

这里采用实现WebMvcConfigurer接口,通过实现extendMessageConverters方法来扩展消息转换器,实现日期格式的统一处理。

1. 简单实现

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.fasterxml.jackson.databind.ObjectMapper;@Configuration // 表明这是一个 Spring 配置类,Spring 容器会自动扫描并加载该配置
public class WebConfig implements WebMvcConfigurer {/*** 扩展 Spring MVC 框架的消息转换器* 这里是通过自定义 Jackson 的 `MappingJackson2HttpMessageConverter` 来处理 JSON 数据* 并为其设置自定义的日期格式* * @param converters Spring MVC 自动传入的消息转换器列表*/@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {// 输出日志,提示消息转换器正在被扩展log.info("扩展消息转换器...");// 创建一个 JSON 消息转换器对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();// 创建一个 ObjectMapper(这是 Jackson 用于将 Java 对象和 JSON 相互转换的工具类)ObjectMapper objectMapper = new ObjectMapper();// 设置日期格式为 "yyyy-MM-dd HH:mm:ss",即:2024-10-15 12:34:56objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));// 将配置好的 ObjectMapper 设置到消息转换器中converter.setObjectMapper(objectMapper);// 将自定义的消息转换器添加到转换器列表的最前面// 这样 Spring MVC 会优先使用这个自定义的转换器converters.add(0, converter);}
}

1.1 主要特点

1.1.1 简单的日期格式配置

这段代码主要通过 ObjectMapper#setDateFormat 方法配置了一个全局的日期格式。它只针对日期格式进行设置,格式"yyyy-MM-dd HH:mm:ss"。在 JSON 数据的序列化和反序列化过程中,所有的 Date 对象都会被转换成这个格式

1.1.2 局限性

  • 这种方式仅适用于 java.util.Date 类和类似的 java.sql.Datejava.sql.Timestamp。对于 Java 8 引入的日期时间 API(如 LocalDateTimeLocalDate)并没有处理。
  • 处理方式较为简单,只适用于某些特定场景。

1.2 适用场景

  1. 简单日期处理需求:如果项目中主要处理的是 java.util.Datejava.sql.Date 这类传统的日期时间类型,而没有使用 Java 8 引入的日期时间类(如 LocalDate, LocalDateTime),那么这段代码足以胜任。这种场景一般在老旧项目或小型应用中较为常见。

  2. 快速实现统一日期格式:如果你仅仅需要为整个应用程序统一格式日期,而不需要处理其他复杂的序列化和反序列化要求,这种方法能快速有效地实现这一需求。

  3. 项目简单,开发周期较短:对于一些简单的 Web 项目或 REST API,尤其是那些不涉及复杂的日期时间操作或对兼容性要求较低的场景,这段代码可以满足需求。

  4. 无复杂 JSON 序列化需求:如果你的项目对 JSON 的序列化和反序列化没有太多特殊需求,且只需要格式日期字段,并且你不想引入太多的复杂配置,这段代码足够简单清晰。

1.3 适用环境

  • 传统的 Java Web 应用,使用的是 Java 7 或更早的版本,项目中可能没有用到 Java 8 的日期时间 API。
  • 轻量级 Web 服务,仅需要处理简单的 Date 时间格式,没有更复杂的定制化需求。

2. 全面处理 Java 日期时间 API

2.1 实现步骤

2.1.1 自定义ObjectMapper类

在自定义的ObjectMapper类中,全面处理Java 日期时间

package com.sky.json;import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
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 java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;/*** 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]*/
public class JacksonObjectMapper extends ObjectMapper {public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";//public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";public JacksonObjectMapper() {super();//收到未知属性时不报异常this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);//反序列化时,属性不存在的兼容处理this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);SimpleModule simpleModule = new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));//注册功能模块 例如,可以添加自定义序列化器和反序列化器this.registerModule(simpleModule);}
}

2.1.2 使用自定义的ObjectMapper

扩展消息转换器中使用自定义的ObjectMapper

public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {log.info("扩展消息转换器...");// 创建一个 JSON 消息转换器对象MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();// 使用自定义的 JacksonObjectMapperconverter.setObjectMapper(new JacksonObjectMapper());// 将自定义的消息转换器添加到转换器列表的最前面converters.add(0, converter);
}

2.2 主要特点

  1. 全面处理 Java 日期时间 API

    • 这段代码通过自定义的 JacksonObjectMapper 实现了对 Java 8 日期时间 API (LocalDate, LocalDateTime, LocalTime) 的序列化和反序列化处理。通过使用 SimpleModule 注册了自定义的序列化器和反序列化器,它们分别使用了特定的日期时间格式
    • 日期格式不仅局限于 java.util.Date,也适用于 java.time.LocalDateLocalDateTimeLocalTime
  2. 自定义反序列化特性

    • 该代码使用 FAIL_ON_UNKNOWN_PROPERTIES 关闭了对未知属性的报错。在反序列化时,如果 JSON 中包含了 Java 类中没有定义的字段,代码不会抛出异常。这使得反序列化过程更加灵活,避免因版本问题或多余字段导致的错误。
  3. 更强的灵活性

    • 通过模块化的方式,将不同的序列化器和反序列化器进行注册,支持对各种复杂对象的灵活处理。适用范围更广,特别是对 Java 8 之后的日期时间 API 处理更加完善。

2.3 适用场景

  1. 使用 Java 8 日期时间 API 的项目:如果你的项目中广泛使用了 Java 8 引入的日期时间类(如 LocalDate, LocalDateTime, LocalTime),并且需要对这些类型进行序列化和反序列化操作,第二段代码更为适合。它通过自定义 ObjectMapper 配置了对这些新日期时间类的处理。

  2. 复杂日期时间处理需求:当你需要对不同的日期时间格式进行精细控制,比如要分别处理日期时间日期时间,并且希望自定义它们的格式(如将时间格式设置为 "HH:mm:ss"),第二段代码提供了更灵活的方案。

  3. 需要忽略未知属性的场景:如果你的项目可能会收到包含额外或未知字段的 JSON 数据,而你不希望反序列化时抛出异常(比如在多版本兼容的场景下),这段代码通过配置 FAIL_ON_UNKNOWN_PROPERTIES 来确保反序列化时能够兼容这些未知字段。

  4. 大型项目或微服务:在大型项目中,通常会涉及复杂的数据对象和灵活的 JSON 处理需求。此时,第二段代码的模块化扩展方式(通过 SimpleModule 注册序列化和反序列化器)使得它能够轻松处理不同的数据类型,具有较高的扩展性和灵活性。

  5. 多类型序列化需求:除了日期时间之外,项目中可能需要对其他复杂的对象进行定制化的序列化和反序列化。这段代码通过 SimpleModule 机制,允许添加额外的序列化器和反序列化器,以满足更多复杂类型的需求。

2.4 适用环境

  • 现代 Java 应用,使用了 Java 8 及以上版本,尤其是项目中广泛使用 LocalDateTimeLocalDate 等 Java 8 日期时间类。
  • 微服务架构项目,需要对不同的服务接口返回的 JSON 进行高度灵活的序列化和反序列化处理。
  • 需要兼容多版本的项目,如果需要处理不同版本的 API 返回的数据,且 JSON 结构可能变化,此代码能够有效处理兼容性问题。
  • 大中型企业级应用,需要对序列化过程进行定制化,比如处理不同格式日期、忽略未知字段、或对不同对象类型进行特殊处理。

3. 总结

  • 第一段代码 适合简单场景,项目对日期时间处理的要求不高,主要用于处理 Date 类的日期时间
  • 第二段代码 适合复杂场景,尤其是使用了 Java 8 日期时间 API 的项目,它能提供更强大的自定义功能和更灵活的序列化与反序列化处理。

http://www.ppmy.cn/devtools/126944.html

相关文章

MongoDB未授权访问

mongodb未授权访问漏洞 复现 MongoDB[//]: # (忙够DB)是一种流行的开源文档数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;基于分布式文件存储的数据库属于NoSQL数据库的一种。 开启MongoDB服务时不添加任何参数时,默认是没有权限验证的 登录的用户可以通过默认端口…

GPT-SoVITS的批量克隆声音并且合并

标是将每一段声音通过GPT-SoVITS的API的API进行克隆&#xff0c;因为拼在一起的整个片段处理会造成内存或者缓存溢出 将目录下的音频文件生成到指定目录下&#xff0c;然后再进行拼接。 通过AI工具箱生成的数据文件是这样的结构&#xff0c;temp目录下是没个片段生成的部分&a…

飞腾D2000加固计算机

在信息技术日新月异的今天&#xff0c;国产CPU的崛起成为了业界关注的焦点。其中&#xff0c;飞腾D2000处理器以其卓越的性能和高度国产化特性&#xff0c;在加固笔记本领域大放异彩。本文将深入探讨飞腾D2000 CPU在国产化加固笔记本中的应用、性能优势、市场反响以及未来展望&…

TCP(三次握手)和UDP(面向无连接)的原理以及区别

TCP(三次握手)和UDP&#xff08;面向无连接&#xff09;的原理以及区别 网络协议是每个前端工程师都必须要掌握的知识&#xff0c;TCP/IP 中有两个具有代表性的传输层协议。 概述 &#x1f4e1;TCP&#xff08;Transmission Control Protocol&#xff09;是一种网络协议&#…

AJAX——HTTP 协议请求报文和响应报文结构

1、HTTP &#xff08;hypertext transport protocol&#xff09;协议【超文本传输协议】&#xff0c;协议详细规定了浏览器和万维网服务器之间互相通信的规则。 2、请求报文&#xff08;浏览器向服务器发送的内容&#xff09; 重点是格式和参数 ① 请求行 请求类型 / url 文件…

uniapp的移动端骨架屏组件开发应用

背景 基于移动端 UI 骨架屏的扩展性受限&#xff0c;uniapp和小程序等不支持Vue框架的自定义指令&#xff08;directives&#xff09;&#xff0c;遂开发组件以实现骨架屏的自定义开发 使用 引入组件 保证演示效果&#xff0c;show默认为true 页面标签自定义绑定 为需要显示骨…

JsonElement 类

JsonElement 是 Gson 库中的一个核心类&#xff0c;它是一个抽象类&#xff0c;代表着 JSON 字符串中的一个元素。这个元素可以是 JsonObject、JsonArray、基本数据类型的 JsonPrimitive&#xff0c;或者是 JsonNull。以下是 JsonElement 类的一些常用方法及其详细解释和代码案…

Navigation2 算法流程

转自 https://zhuanlan.zhihu.com/p/405670882 此文仅作学习笔记 启动流程 在仿真环境中启动导航包的示例程序&#xff0c;执行nav2_bringup/bringup/launch/tb3_simulation_launch.py文件。ROS2的launch文件支持采用python语言来编写以支持更加复杂的功能&#xff0c;本文件…