2017-11-24 1 views
0

다른 국가에있는 다른 시간대에있는 클라이언트와 함께 spring-boot 웹 프로젝트 프로젝트를 진행하고 있습니다. 데이터베이스에 UTC로 날짜/시간을 저장합니다. 또한 spring-mvc, spring-data-jpa, hibernateJava time API (Java 8)을 사용하고 있습니다. 요구 사항 중 하나는 사용자에게 현지 날짜 시간 및 형식을 사용자 로캘에 따라 표시하는 것입니다.현지 시간 및 다른 시간대의 형식을 표시하는 날짜/시간을 UTC로 저장합니다.

제 질문은 어디에서나 날짜/시간 변환을 사용하여 코드를 오염시키지 않도록 가능한 한 투명하게 만드는 가장 좋은 장소입니다. 가장 먼저 생각해 보면, 필터를 사용하여 요청/응답을 가로 채고 현재 사용자와 연결된 ThreadLocal 객체에서 위치를 가져 오는 변환을 만들지 만,이 시점에서 데이터는 여전히 너무 원시입니다. 또 다른 대안은 최대 절전 모드가있는 인터셉터를 사용하여 저장하기 전과 읽은 후에 변환을 수행하는 것입니다.

제안 사항을 이해하고 가능한 경우 지정된 솔루션의 최종 장점과 단점을 높이 평가합니다.

답변

1

요격기 나 필터 소리를 사용하여 과장된 소리를 들려줍니다. 사용자 시간대로 변환 할 수있는 datetime 필드에 대한 각 요청을 확인하는 것은 특정 datetime 필드를 사용자 특정 시간대로 변환하려는 경우 너무 많습니다.

더 쉬운 접근법은 클라이언트 측에서/클라이언트 측으로 자바 객체를 직렬화 할 때 사용자 정의 JsonSerializerJsonDeserializer을 지정하는 것입니다. Java 8을 사용하기 때문에 ZonedDateTime을 사용하여 DateTime과 Zone을 하나의 필드에 저장할 수 있습니다.

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), 동시성은 어떨까요? serializer/deserializer가 싱글 톤이 될 것이라고 생각합니다. 맞습니까? 그들이 싱글 톤인 경우 각 클라이언트에 올바른 httpSession을 주입 할 것이라는 보장은 없습니다. 이 경우에는 ThreadLocal 접근 방식이 더 잘 작동한다고 생각합니다. DTO 주석을 추가 할 필요없이 기본적으로 serializer/deserializer를 정의 할 수 있습니까? –

+0

예, 직렬/직렬 변환기는 싱글 렛이며 httpsession은 물론 세션 범위입니다. 이 경우 사용자에게 올바른 세션을 가져 오는 것에 대해 걱정할 필요가 없습니다. 봄이 처리합니다. Spring은 httpsession을 지능적으로 주입하고 내부적으로 적절한 사용자에게 위임합니다. [this] (https://dzone.com/articles/using-http-session-spring)을 참조하십시오. dirty에서 좋은 기사 – Bnrdo

+0

의미가 있습니다, 수락 :-) –

관련 문제