解决 SpringBoot 的 Date、LocalDateTime 变成时间戳和数组的问题,创建自定义对象消息转换器

news2024/11/18 20:42:11

问题描述

SpringBoot 项目,当返回前端的数据类型为 Map 的时候,在 Map 中 put() 时间对象会出现以下问题:

  • 传递的 Date 对象会变成时间戳
  • 传递的 LocalDateTime 对象会变成数组

问题复现

编写一个 Controller 方法,返回值为 Map,分别 put() Date 对象和 LocalDateTime 对象。

@RestController
@RequestMapping("test")
public class TestController {
    @ApiOperation("t1")
    @GetMapping("t1")
    public Map<String, Object> t1() {
        return new HashMap<String , Object>(){{
            put("java.util.Date", new Date());
            put("java.time.LocalDate", LocalDate.now());
            put("java.time.LocalTime", LocalTime.now());
            put("java.time.LocalDateTime", LocalDateTime.now());
        }};
    }
}

访问接口,获得的数据如下,可以看到 Date 对象被转换成时间戳,而 LocalDateTime 对象被转换成数组。

在这里插入图片描述

解决问题

在上面复现问题时,我们发现 DateLocalDateLocalTimeLocalDateTime 对象数据在返回给前端的时候,并不是我们预期想要的值,在 SpringBoot 中,支持我们自定义对象类型的消息转换器,可以分别为各种对象的数据进行格式化,下面案例对 DateLocalDateLocalTimeLocalDateTime 四个对象进行消息转换。

创建自定义消息处理器可以通过重写 WebMvcConfigurer.extendMessageConverters() 方法来实现,代码如下:

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
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 java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
 * @author jiale
 */
@Configuration // 配置注解记得加上
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 扩展的消息转换器
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        /*
         * 解决 LocalDateTime 返回给前端会变成数组的问题
         */
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = converter.getObjectMapper();
        // 不显示为 null 的字段
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleModule module = new SimpleModule();
        // Date 消息转换器
        module.addSerializer(Date.class, new JsonSerializer<Date>() {
            @Override
            public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                // 对时间进行格式化,返回数据为字符串类型
                jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
            }
        });
        // LocalDate 消息转换器
        module.addSerializer(LocalDate.class, new JsonSerializer<LocalDate>() {
            @Override
            public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(localDate));
            }
        });
        // LocalTime 消息转换器
        module.addSerializer(LocalTime.class, new JsonSerializer<LocalTime>() {
            @Override
            public void serialize(LocalTime localTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ofPattern("HH:mm:ss").format(localTime));
            }
        });
        // LocalDateTime 消息转换器
        module.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
            @Override
            public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(localDateTime));
            }
        });
      	// 如果还需要其它对象的消息转换器,就继续通过 module.addSerializer() 添加 
        mapper.registerModule(module);
        converter.setObjectMapper(mapper);
        // SpringBoot 默认提供了好多个消息转换器,这里把我们自定义的消息转换器放首个位置
        converters.add(0, converter);
    }
}

添加时间对象的消息处理器之后,返回前端的数据如下:

在这里插入图片描述

问题搞定!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1692402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全基础技术扫盲篇 — 名词解释

网络模块基础&#xff08;网络拓扑图、网络设备、安全设备&#xff09; 用通俗易懂的话说&#xff1a; 网络拓扑图&#xff1a;它就像一张网络世界的地图&#xff0c;它展现了我们数不清的网站、服务器和设备是如何相互连接的。用简单的话说&#xff0c;它就是给我们指路、告…

企业ov代码签名证书1300

我们在下载一些软件代码时&#xff0c;有时候操作系统会出现未知软件拦截&#xff0c;各个杀毒软件也会因为软件身份不明拦截软件下载。而代码签名证书可以对软件进行数字签名&#xff0c;以验证软件的身份和完整性。这种数字签名机制确保了软件在传输和安装过程中没有被篡改或…

数据结构---优先级队列(堆)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 关注博主带你了解更多数据结构知识 1. 优先级队列 1.1 概念 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队 列时&am…

Rust 赋能前端 -- 写一个 File 转 Img 的功能

所有耀眼的成绩,都需要苦熬,熬得过,出众;熬不过,出局 大家好,我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder 此篇文章所涉及到的技术有 Rustwasm-bindgen/js-sys/web-sysWeb WorkerWebAssemblyWebpack/Vite配置WebAssemblyOffscreenCanvas脚手架生成项…

win11缺少msvcr110dll,msvcp110.dll的解决办法

MSVCP110.dll是一个与Microsoft Visual C 2012 Redistributable Package相关的动态链接库&#xff08;Dynamic Link Library&#xff09;文件&#xff0c;主要用于支持使用C编写的Windows应用程序运行时所需的特定功能。当用户尝试运行依赖于这个库的应用程序时&#xff0c;如果…

【网络安全】网络安全协议的重要性

一.网络安全 1.什么是网络安全 网络安全&#xff08;Cyber Security&#xff09;是指网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然的或者恶意的原因而遭受到破坏、更改、泄露&#xff0c;系统连续可靠正常地运行&#xff0c;网络服务不中断。 2.网络安…

智慧展厅设计的难点有哪些

1、运用先进的展示技术 将全息影像、三维投影、虚拟现实、人机互动等技术做做完美衔接&#xff0c;把展厅的内容展示做到丰富多彩&#xff0c;从而让展厅富有科技感和艺术性。 2、内容要生动有趣 从而更好地吸引参观者。展厅设计师要与客户有良好深入的沟通&#xff0c;搜集与整…

SAP 批量获取BOM中替代料信息(代码分享)

最近用户需要到导出BOM中存在替代料的信息,只要导出替代料的程序,但是使用展开BOM的程序执行后,导致执行时间很长,数量量也非常的大,内存溢出,程序就挂掉了。9万多个物料有BOM,当然不能让用户去导,后面我们写了一段SQL,用内表的方式给用户导出了需要的数据。 同时也找…

10.8k star,超好用的高颜值屏幕录制工具

最近公司需要给新来的同事做一些基础的培训。不过因为时间冲突&#xff0c;没办法现场给大家上课&#xff0c;所以老板让我自己在家把视频课程录制好&#xff0c;还说要让同事们看到我的样子。 这倒是有点费劲了&#xff0c;之前也录制过课程视频&#xff0c;但都是直接用屏幕…

小程序-修改用户头像

1、调用拍照 / 选择图片 // 修改头像 const onAvatarChange () > { // 调用拍照 / 选择图片 uni.chooseMedia({ // 文件个数 count: 1, // 文件类型 mediaType: [image], success: (res) > { console.log(res) // 本地临时文件路径 (本地路径) const { tempFilePath } …

【Tools】SpringBoot工程中,对于时间属性从后端返回到前端的格式问题

Catalog 时间属性格式问题一、需求二、怎么使用 时间属性格式问题 一、需求 对于表中时间字段&#xff0c;后端创建对应的实体类的时间属性需要设定格式&#xff08;默认的格式不方便阅读&#xff09;&#xff0c;再返回给前端。 二、怎么使用 导入jackson相关的坐标&#x…

PostgreSQL事务基础理解

PostgreSQL事务 事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。数据库事务通常包含一个序列对数据库的读和写操作&#xff0c;主要是包含以下两个目的&#xff1a; 为数据库操作序列提供一个从失败中恢复到正常状态的方法&#…

vue 打印、自定义打印、页面打印、隐藏页眉页脚

花了一天时间搞了个打印功能&#xff0c;现则将整体实现过程进行整理分享。先来看看效果图&#xff1a; 1、页面展示为&#xff1a; 2、重组页面打印格式为&#xff1a;这里重组页面的原因是客户要求为一行两列打印 &#xff01;内容过于多的行则独占一行显示完整。 整体实现&…

isscc2024 short course2 Performance Compute Environment

这部分分为4部分&#xff1a; 概览&#xff1a;LLMs和生成式AI 探讨大语言模型&#xff08;LLMs&#xff09;和生成式AI的整体环境&#xff0c;及其对硬件加速器设计的影响。 高性能AI加速器的特定考虑因素 广泛的模型和使用案例支持&#xff1a;需要设计能支持多种模型和应…

python中的线程并行

文章目录 1. 单线程2. 线程池ThreadPoolExecutor 1. 单线程 现在有1154张图片需要顺时针旋转后保存到本地&#xff0c;一般使用循环1154次处理&#xff0c;具体代码如下所示&#xff0c;img_paths中存储1154个图片路径&#xff0c;该代码段耗时约用97ms。 t1time.time() for …

SpringCloud系列(30)--准备使用Hystrix的前期工作,创建服务消费者模块

前言&#xff1a;在上一章节中我们创建了服务提供者模块&#xff0c;而本节内容则是创建服务消费者模块。 1、创建一个服务提供者模块&#xff0c;命名为cloud-consumer-feign-hystrix-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选择模块要使用的JDK版本 …

面向Prompt编程

Prompt 就像和一个人对话&#xff0c;你说一句&#xff0c;ta 回一句&#xff0c;你再说一句&#xff0c;ta 再回一句…… Prompt 就是你发给大模型的指令&#xff0c;比如「讲个笑话」、「用 Python 编个贪吃蛇游戏」、「给男/女朋友写封情书」等 貌似简单&#xff0c;但意义…

vue项目实战 - 如果高效的实现防抖和节流

在Vue项目中&#xff0c;处理高频事件的优化至关重要&#xff0c;直接影响用户体验和应用性能。防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;是两种常用且有效的方法&#xff0c;可以控制事件触发频率&#xff0c;减少不必要的资源消耗。如何在…

labview_开放协议

一、开放协议 二、硬件设置 英格索兰硬件设置&#xff1a; 三、配套测试软件 四、Labview代码

科技赋能,打破视障人士的沟通壁垒

在探索如何增强盲人群体的社会参与度与幸福感的旅程中&#xff0c;盲人社交能力提升策略成为了不容忽视的一环。随着科技的不断进步&#xff0c;像“蝙蝠避障”这样的辅助软件&#xff0c;不仅在日常出行中为盲人提供了实时避障和拍照识别的便利&#xff0c;也在无形中为他们拓…