[spring] LocaleResolver 개요

GuruneLee·2023년 1월 1일
0

Let's Study 공부해요~

목록 보기
29/36
post-thumbnail

Locale 이란?

  • 자바에서 Locale 이란 나라, 언어 등 지리적/문화적으로 분리된 지역들에 대한 정보를 담고있는 객체다.
  • Locale-sensitive 한 서비스는 여러 방법으로 클라이언트의 locale 을 얻고/저장하고/불러와야 한다.
    • accept-language 헤더, request params, cookie / session 등의 방법이 쓰일 수 있다.

LocaleResolver

request 로부터의 locale resolution 과 request-response 간 locale 수정 전략을 선언한 인터페이스.

resolveLocale, setLocale 두 가지 메서드가 선언되어있다.

  • Locale resolveLocale(HttpServletRequest request)
  • void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale)

이렇게만 보면 잘 이해가 안가니, 기본값으로 Bean으로 등록되는 AcceptHeaderLocaleResolver 를 예시로 동작을 살펴보자.

AcceptHeaderLocaleResolver

AcceptHeaderLocaleResolverLocaleResolver 를 구현하며, 다음과 같이 Http 헤더의 'accept-language'에 담겨오는 locale 정보를 얻어온다.

오버라이드 된 resolveLocale 메서드 코드를 보자

@Override
public Locale resolveLocale(HttpServletRequest request) {
    Locale defaultLocale = getDefaultLocale();
 
    if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
        return defaultLocale;
    }
 
    Locale requestLocale = request.getLocale();
    List<Locale> supportedLocales = getSupportedLocales();
    if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
        return requestLocale;
    }
    Locale supportedLocale = findSupportedLocale(request, supportedLocales);
    if (supportedLocale != null) {
        return supportedLocale;
    }
    return (defaultLocale != null ? defaultLocale : requestLocale);
}
  • servlet request 의 Accept-Language 헤더 값이 없으면 defaultLocale을 리턴한다
  • request 에서 getLocale 메서드로 로케일을 받아와서 지원하는 Locale인지 확인 후, 적절한 값을 리턴하는 형태다.

LocaleContextHolder

localeResolver 메서드엔 locale을 어디 저장하는 로직이 없지만, 스프링에선 리졸빙한Locale을 LocaleContextHolder에 저장한다

// DispatcherServlet.java
// buildLocaleContext: 등록된 리졸버에서 뽑은 locale을 LocaleContext로 만들어 반환하는 함수
...
    @Override
    protected LocaleContext buildLocaleContext(final HttpServletRequest request) {
        LocaleResolver lr = this.localeResolver;
        if (lr instanceof LocaleContextResolver) {
            return ((LocaleContextResolver) lr).resolveLocaleContext(request);
        }
        else {
            return () -> (lr != null ? lr.resolveLocale(request) : request.getLocale());
        }
    }
...
 
// FrameworkServlet.java
// initContextHolders: localeConetext를 받아서 LocaleContextHolder에 저장
...
    private void initContextHolders(HttpServletRequest request,
            @Nullable LocaleContext localeContext, @Nullable RequestAttributes requestAttributes) {
 
        if (localeContext != null) {
            LocaleContextHolder.setLocaleContext(localeContext, this.threadContextInheritable);
        }
        if (requestAttributes != null) {
            RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
        }
    }
...

이렇게 LocaleResolver를 통해 추출되어 LocaleContextHolder에 저장된 Locale정보는, LocaleContextHolderstatic getLocale() 메서드를 이용해 사용할 수 있다.

profile
Today, I Shoveled AGAIN....

0개의 댓글