2017-11-24 17 views
0

私はspring-bootウェブアプリケーションプロジェクトで、さまざまな国の異なるタイムゾーンにあるクライアントと一緒に作業しています。私は日付/時刻をUTCでデータベースに保存しています。また、spring-mvc,spring-data-jpahibernateJava time API(Java 8)を使用しています。要件の1つは、ユーザーにロケールに応じて(ユーザープロファイルから)ローカル日付の時刻と形式を表示することです。日付/時刻をUTCで保存し、現地時間と異なるタイムゾーンでのフォーマットを表示します。

私の質問は、日付/時刻の変換を使用してどこでもコードを汚染しないように、できるだけ透明なものにするのに最適な場所です。私の頭に浮かぶ最初のことは、リクエスト/レスポンスを傍受し、現在のユーザに関連付けられたThreadLocalオブジェクトから位置を取得するためにフィルタを使用することですが、この時点ではまだデータは未加工です。もう1つの方法は、インターセプターを休止状態にして、保存前と読み取り後に変換を行うことです。

私は、任意の提案と、可能であれば、指定されたソリューションの最終的な長所と短所を感謝します。

答えて

1

インターセプタまたはフィルタサウンドを使用して、私に過度のサウンドを与えます。特定の日時フィールドをユーザー固有のタイムゾーンに変換するだけの場合、ユーザーのタイムゾーンに変換できる日時フィールドの各要求を確認することは多すぎます。

より簡単なアプローチは、クライアント側との間でJavaオブジェクトをデシリアライズするときにカスタムJsonSerializerJsonDeserializerを指定することです。 Java 8を使用しているので、ZonedDateTimeを使用してDateTimeとZoneを1つのフィールドに格納できます。

userTimeZoneをセッションに格納するのが一般的です。カスタムシリアライザは、セッションを挿入してそこに保存されているuserTimeZoneを取得できるように、春の豆である必要があります。クライアント側に

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; 
    } 
} 

シリアライザ、あなたのハンドラから:

はあなたにいくつかのpsuecode

DTOを共有

@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に簡単に注釈を付けることができます。

+0

こんにちは[@Bnrdo](https://stackoverflow.com/users/1767366/bnrdo)、並行処理はどうですか?私はシリアライザ/デシリアライザがシングルトンになるだろうと思っています。シングルトンの場合、各クライアントに対して適切なhttpSessionを注入するという保証はありません。私はこの場合、ThreadLocalアプローチがうまくいくと思います。 DTOアノテーションを追加する必要なくシリアライザ/デシリアライザをデフォルトで定義する機会はありますか? –

+0

はい、シリアライザはシングルレングスで、httpsessionはセッションスコープです。その場合、ユーザーにとって正しいセッションを取得することについて心配する必要はありません。春はそれを処理します。 Springはhttpsessionのインテリジェントなプロキシインジェクションを行い、それを適切なユーザに内部的に委譲します。 [this](https://dzone.com/articles/using-http-session-spring)を参照してください。d土曜日の素敵な記事 – Bnrdo

+0

意味を成して、受け入れる:-) –

関連する問題