当前位置: 首页 > news >正文

Java controller接口出入参时间序列化转换操作

场景:在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:适配自定义序列化和反序列化策略*/@Beanpublic 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 static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {@Overridepublic void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)throws IOException {if (value != null) {// 通过配置决定把时间转换成 时间戳 或 时间字符串if ("timestamp".equals(LOCAL_DATE_TIME_SERIALIZER_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> {@Overridepublic 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;}// 如果是格式化时间字符串} 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 userRO){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;}

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

http://www.xdnf.cn/news/209233.html

相关文章:

  • AimRT 从零到一:官方示例精讲 —— 六、pb_chn示例.md
  • OpenObserve API Usage Guide for Log Management
  • 四则运算+从单向链表中删除指定值的节点+名字的漂亮度+数独(Sudoku)
  • Dali 1.1.4 | 使用尖端技术将描述转换成独特艺术品、照片和图像,发挥无限创意
  • npm如何安装pnpm
  • Flip PDF Plus Corp7.7.22电子书制作软件
  • AimRT 从零到一:官方示例精讲 —— 一、工具链与基本概念
  • css3伸缩盒模型第一章(主轴以及伸缩盒模型)
  • P1903 [国家集训队] 数颜色 / 维护队列 Solution
  • neo4j暴露公网ip接口——给大模型联通知识图谱
  • Python 使用一等函数实现设计模式(案例分析:重构“策略”模式)
  • Linux 服务管理两种方式service和systemctl
  • Node.js 事件循环和线程池任务完整指南​
  • 香港科技大学广州|可持续能源与环境学域博士招生宣讲会—四川大学专场
  • 阿里云服务迁移实战: 05-OSS迁移
  • 【Linux系统】systemV共享内存
  • 基于tabula对pdf中多个excel进行识别并转换成word中的优化(五)
  • Go语言之路————接口、泛型
  • SpringMVC再复习1
  • MODSIM选型指南:汽车与航空航天企业如何选择仿真平台
  • 极客天成参与”AI助力智慧城市构建”主题演讲暨招商引智专题推介活动
  • 哈希表笔记(一 )
  • 【东枫电子】AI-RAN:利用人工智能驱动的计算基础设施变革 RAN
  • 后端部署:Flask + pymysql + MySQL迁移到服务器(以Linux为例)
  • Android Framework常见问题
  • 包装类的缓存机制
  • SELinux 从理论到实践:深入解析与实战指南
  • 算法题(137):丢手绢
  • 在yolo中Ultralytics是什么意思呢?超越分析的智能
  • 篮球足球体育球员综合资讯网站模板