本文主要是介绍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接口出入参内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!
这篇关于Java controller接口出入参时间序列化转换操作方法(两种)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!