Java controller接口出入參時間序列化轉換操作方法(兩種)
場景:在controller編寫的接口,在前后端交互過程中一般都會涉及到時間字段的交互,比如:后端給前端返的數(shù)據(jù)有時間相關的字段,同樣,前端也存在傳時間相關的字段給后端,最原始的方式就是前后端都先轉換成字符串和時間戳后進行傳輸,收到后再進行轉換,特別麻煩。
為了方便可以使用注解或者配置做到時間字段的自動轉換,這里列舉兩種簡單的操作。
方式一、使用注解
就是在日期字段上添加對應的注解(@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;優(yōu)點:靈活、清晰。
缺點:所有需要轉換的字段都需要手動添加、并且只支持時間和指定格式字符串互轉,不支持時間戳
方式二、統(tǒng)一配置
一勞永逸的方式,支持時間和 時間戳、字符串 之間的互轉
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類型數(shù)據(jù)轉化為string給前端 避免前端造成的精度丟失
builder.serializerByType(Long.class, ToStringSerializer.instance);
builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
};
}
/**
* description:序列化
* LocalDateTime序列化為毫秒級時間戳
*/
public static 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_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> {
@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;
}
// 如果是格式化時間字符串
} 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;
}
通過配置類,可以配置后端接口給調用方返的時間格式【字符串、時間戳】、接口調用方傳的入參可以是字符串也可以的時間戳,后端會自動解析。
到此這篇關于Java controller接口出入參時間序列化轉換操作方法(兩種)的文章就介紹到這了,更多相關Java controller接口出入參內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- java idea如何根據(jù)請求路徑url自動找到對應controller方法插件
- Java中Controller、Service、Dao/Mapper層的區(qū)別與用法
- Java實現(xiàn)一鍵生成表controller,service,mapper文件
- Java中Controller引起的Ambiguous?mapping問題及解決
- 詳解java封裝返回結果與RestControllerAdvice注解
- Java后臺Controller實現(xiàn)文件下載操作
- java springboot poi 從controller 接收不同類型excel 文件處理
- java模擬ajax訪問另一個項目的controller代碼實例
- Java Spring Controller 獲取請求參數(shù)的幾種方法詳解
相關文章
Spring Scheduler定時任務實戰(zhàn)指南(零基礎入門任務調度)
本文介紹SpringScheduler在電商訂單超時處理中的應用,涵蓋啟用定時任務、使用@Scheduled注解、cron表達式配置、線程池優(yōu)化及異步執(zhí)行等核心內容,本文給大家介紹Spring Scheduler定時任務實戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧2025-09-09
SpringBoot接收前端參數(shù)的最常用的場景和具體案例
在SpringBoot開發(fā)中接收參數(shù)是非常常見且重要的一部分,依賴于請求的不同場景,Spring?Boot提供了多種方式來處理和接收參數(shù),項目小編就和大家簡單講講SpringBoot接收前端參數(shù)的3 個最常用的場景和具體案例2025-11-11
關于MyBatis通用Mapper@Table注解使用的注意點
這篇文章主要介紹了關于MyBatis通用Mapper@Table注解使用的注意點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
SpringCloud使用CircuitBreaker實現(xiàn)熔斷器的詳細步驟
在微服務架構中,服務之間的依賴調用非常頻繁,當一個下游服務因高負載或故障導致響應變慢或不可用時,可能會引發(fā)上游服務的級聯(lián)故障,最終導致整個系統(tǒng)崩潰,熔斷器是解決這類問題的關鍵模式之一,Spring Cloud提供了對熔斷器的支持,本文將詳細介紹如何集成和使用它2025-02-02

