Java controller接口出入参时间序列化转换操作方法(两种)

本文主要是介绍Java controller接口出入参时间序列化转换操作方法(两种),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看...

场景:在controller编写的接口,在前后端交互过程中一般都会涉及到时间字段的交互,比如:后端给前端返的数据有时间相关的字段,同样,前端也存在传时间相关的字段给后端,最原始的方式就是前后端都先转换成字符串和时间戳后进行传输,收到后再进行转换,特别麻烦。
为了方便可以使用注解或者配置做到时间字段的自动转换,这里列举两种简单的操作。

方式一、使用注解

就是在日期字段上添加对应的注解(@jsonFormat),例:

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime2;
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime3;

优点:灵活、清晰。
缺点:所有需要转换的字段都需要手动添加、并且只支持时间和指定格式字符串互转,不支持时间戳

方式二、统一配置

一劳永逸的方式,支持时间和 时间戳、字符串 之间的互转

package com.zhh.demo.config;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import com.fasterXML.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import Java.io.IOException;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
//@EnableASPectJAutoProxy(exposeProxy = true)
public class ApplicationConfig {
    /** 年-月-日 时:分:秒 */
    private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * 序列化 时间格式转换类型
     * timestamp:时间戳
     * dateString: 时间字符串格式
     * */
    private static final String LOCAL_DATE_TIME_SERIALIZER_TYPE = "dateString";
    /**
     * description:适配自定义序列化和反序列化策略
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            // 时间的序列化和反序列化
            builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer());
            builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer());
            // 将long类型数据转化为string给前端 避免前端造成的精度丢失
            builder.serializerByType(Long.class, ToStringSerializer.instance);
            builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
        };
    }
    /**
     * description:序列化
     * LocalDateTime序列化为毫秒级时间戳
     */
    public statiChina编程c class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException {
            if (value != null) {编程
                // 通过配置决定把时间转换成 时间戳 或 时间字符串
                if ("timestamp".equals(LOCAL_DATE_TIME_SERIALIZEpythonR_TYPE)) {
                    // 13位时间戳
                    gen.writeNumber(LocalDateTimeUtil.toEpochMilli(value));
                } else {
                    // 指定格式的时间字符串
                    gen.writeString(value.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
                }
            }
        }
    }
    /**
     * description:反序列化
     * 毫秒级时间戳序列化为LocalDateTime
     */
    public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
                throws IOException {
            //2023年11月2日: 尝试反序列增加更多的支持, 支持long输入, 支持字符串输入
            if (p == null) {
                return null;
            }
            String source = p.getText();
            return parse(source);
        }
    }
    /**
     * 时间戳字符串或格式化时间字符串转换为 LocalDateTime
     * 例:1745806578000、2025-04-28 10:16:18
     * @param source    13位时间戳 或格式化时间字符串
     * @return
     */
    private static LocalDateTime parse(String source) {
        // 如果是时间戳
        if (NumberUtil.isLong(source)) {
            long timestamp = Long.parseLong(source);
            if (timestamp > 0) {
                return LocalDateTimeUtil.of(timestamp, ZoneOffset.of("+8"));
            } else {
                return null;
            }
            // 如果是格式化时间字符串
 www.chinasem.cn       } else {
            if (StringUtils.isBlank(source)) {
                return null;
            }
            // 尝试判断能否解析
            if (canParseByDateTimeFormatter(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) {
                return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
            }
            return null;
        }
    }
    /**
     * 判断是否能解析格式化时间字符串
     * @param source    格式化时间字符串(格式 2025-04-28 10:16:18)
     * @param dateTimeFormatter 格式 yyyy-MM-dd HH:mm:ss
     * @return
     */
    private static boolean canParseByDateTimeFormatter(String source, DateTimeFormatter dateTimeFormatter) {
        try {
            dateTimeFormatter.parse(source);
        } catch (DateTimeParseException e) {
            return false;
        }
        return true;
    }
}

测试一下:
在上面配置的基础上添加部分测试使用的代码

用于前后端交互的bean对象:

@Data
public class UserRO {
    private LocalDateTime createTime1;
    private LocalDateTime createTime2;
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime3;
}

controller层接口:

   @ApiOperation("时间测试")
    @PostMapping("/time")
    public UserRO show(@RequestBody UserRO userRjavascriptO){
        System.out.println("\n接收到的入参:");
        System.out.println(userRO.getCreateTime1());
        System.out.println(userRO.getCreateTime2());
        System.out.println(userRO.getCreateTime3());
        System.out.println("\n出参:");
        LocalDateTime newTime = LocalDateTime.now();
        UserRO user = new UserRO();
        user.setCreateTime1(newTime);
        user.setCreateTime2(newTime);
        user.setCreateTime3(new Date());
        System.out.println(user.getCreateTime1());
        System.out.println(user.getCreateTime2());
        System.out.println(user.getCreateTime3());
        System.out.println("\n");
        return user;
    }

Java controller接口出入参时间序列化转换操作方法(两种)

通过配置类,可以配置后端接口给调用方返的时间格式【字符串、时间戳】、接口调用方传的入参可以是字符串也可以的时间戳,后端会自动解析。

到此这篇关于Java controller接口出入参时间序列化转换操作方法(两种)的文章就介绍到这了,更多相关Java controller接口出入参内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于Java controller接口出入参时间序列化转换操作方法(两种)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154439

相关文章

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环