我正在开展一个spring-boot
WebApp项目,其客户位于不同的时区,最终位于不同的国家/地区。我将日期/时间以UTC格式存储在数据库中。我还使用spring-mvc
,spring-data-jpa
与hibernate
和Java time API
(Java 8)。其中一个要求是向用户显示相应于其区域设置的本地日期时间和格式(来自用户配置文件)。
我的问题是尽可能保持透明的最佳位置,以避免在日期/时间转换中污染代码。我想到的第一件事是使用Filter拦截请求/响应并使转换从与当前用户关联的ThreadLocal对象获取位置,但是在这一点上,数据仍然太原始。另一种方法是使用具有休眠功能的拦截器,并在保存之前和阅读之后进行转换。
我感谢任何建议,如果可能的话,还有指定解决方案的最终优点和缺点。
答案 0 :(得分:1)
使用拦截器或过滤器声音对我来说太过分了。当您只想将特定日期时间字段转换为用户特定时区时,检查每个可转换为用户时区的日期时间字段请求太多。
更容易的方法是在将java对象反序列化到客户端/从客户端序列化时指定自定义JsonSerializer
和JsonDeserializer
。由于您使用的是Java 8,因此可以使用ZonedDateTime将DateTime和Zone一起存储在一个字段中。
将userTimeZone存储在会话中是一种常见做法。自定义序列化程序需要是spring bean,以便您可以注入会话,然后获取保存在其中的userTimeZone。
分享你的一些psuecode
DTO:
public class TheDTO {
@JsonSerialize(using = UserTimeZoneAwareSerializer.class)
@JsonDeserialize(using = UserTimeZoneAwareDeserializer.class)
private ZonedDateTime dateTime;
public ZonedDateTime getDateTime() {
return dateTime;
}
public void setDateTime(ZonedDateTime dateTime) {
this.dateTime = dateTime;
}
}
序列化程序,从处理程序到客户端:
@Component
public class UserTimeZoneAwareSerializer extends JsonSerializer<ZonedDateTime> {
@Autowired
private HttpSession httpSession;
@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
// Grab the userTimeZone from the session then convert from UTC to userTimeZone
gen.writeObject(/**/);
}
}
反序列化器,从客户端到处理程序:
@Component
public class UserTimeZoneAwareDeserializer extends JsonDeserializer<ZonedDateTime> {
@Autowired
private HttpSession httpSession;
@Override
public ZonedDateTime deserialize(JsonParser p, DeserializationContext ctxt)
// Grab the userTimeZone then convert from userTimeZone to UTC
// ...
}
}
这样,您就可以轻松注释要了解用户时区的ZonedDateTime
字段。