spring Boot 項目中自定義 mysql datetime 數據顯示時區
在 spring boot 應用中,MySQL datetime 類型數據默認使用服務器時區顯示。為滿足不同用戶時區需求,需要自定義顯示時區。
解決方案:
本方案通過自定義 Jackson 序列化器實現。
-
創建自定義 Jackson 序列化器: 編寫一個繼承自 StdSerializer
的自定義序列化器,重寫 serialize 方法。該方法負責根據用戶時區格式化日期時間數據。 -
注冊自定義序列化器: 通過 @Bean 注解創建一個 Jackson2ObjectMapperBuilder bean,并使用 serializerByType 方法注冊自定義序列化器,使其應用于所有 Date 類型字段。
-
獲取用戶時區: 在自定義序列化器中,您可以通過 HttpservletRequest 對象獲取客戶端的時區信息 (例如,從請求頭 Accept-Language 或自定義頭中提取)。 如果沒有用戶時區信息,則使用默認時區。
示例代碼:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; @Configuration public class DateTimeConfig { @Bean @Primary public Jackson2ObjectMapperBuilderCustomizer customizer(HttpServletRequest request) { return builder -> builder.serializerByType(Date.class, new CustomDateSerializer(request)); } public static class CustomDateSerializer extends StdSerializer<Date> { private final HttpServletRequest request; public CustomDateSerializer(HttpServletRequest request) { super(Date.class); this.request = request; } @Override public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException { TimeZone timeZone = getTimeZone(request); // 獲取用戶時區,如果沒有則使用默認時區 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(timeZone); gen.writeString(dateFormat.format(value)); } private TimeZone getTimeZone(HttpServletRequest request) { // 從請求頭或其他地方獲取用戶時區信息 String timeZoneStr = request.getHeader("X-Timezone"); // 例如,自定義請求頭 "X-Timezone" if (timeZoneStr != null) { return TimeZone.getTimeZone(timeZoneStr); } else { return TimeZone.getDefault(); // 使用默認時區 } } } }
注意:
- 數據庫中的 datetime 數據類型保持不變。
- 此自定義序列化器僅在序列化和反序列化過程中生效,不影響數據庫數據。
- 需要在你的項目中引入 javax.servlet 包,并確保 HttpServletRequest 可以被注入到 customizer 方法中。 這通常需要依賴于 Spring mvc 或類似的框架。 你可以根據你的項目結構調整代碼。 例如,如果你的 DateTimeConfig 類不是在 spring mvc 的上下文中,你需要尋找其他方法來獲取 HttpServletRequest 對象。
此方案提供了更靈活的時區處理方式,允許根據用戶請求動態調整 datetime 數據的顯示時區。 記得替換 “X-Timezone” 為你實際使用的請求頭名稱。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END