[Spring] Session 레벨에서 다국어 지원하기

dondonee·2023년 11월 3일
0

Session 레벨에서 다국어 지원하기

스프링 강의 내용을 적용해보기 위해 간단한 투두리스트를 만들어보고 있다. 이번에는 메시지, 국제화에 대해 배웠기 때문에 다국어 기능을 추가해보기로 했다.

  • 표시 언어: 기본적으로 한국어, 사용자가 영어를 선택하는 경우에만 영어로 표시

애플리케이션이 언어 정보, 즉 로케일 정보를 어디서 관리할 것인지는 여러 방식으로 선택할 수 있다. 다국어 기능을 위해서 세션이나 쿠키를 많이 사용하는 것 같은데, 아직 쿠키 강의는 아직 듣지 않았기 때문에 세션 방식을 해 보기로 했다.


기본적인 방법

빈 설정하기

@Configuration
public class LocaleConfig {

 @Bean
 public SessionLocaleResolver localeResolver() {
  SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
  sessionLocaleResolver.setDefaultLocale(new Locale("ko"));
  return sessionLocaleResolver;
}
  • config 패키지 아래 LocaleConfig 컨트롤러를 만들고 SessionLocaleResolver 빈을 추가해주었다.
  • setDefaultLocale()을 통해 기본 로케일을 설정해준다.
    • 로케일은 미리 만들어진 로케일 상수보다는 생성자를 이용해 새롭게 만들어주는 것이 좋다고 한다. 만들어져 있는 로케일은 한정적이기 때문에 기존에 없는 새로운 로케일을 추가할 경우 코드의 일관성을 해치기 때문이다.

컨트롤러에서 처리하기

@Slf4j
@Controller
public class configController {

 @GetMapping("/lang")
 public String changeLocale(@RequestParam("lang") String language, HttpSession session) {
  session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale(language));
  log.info("Locale={}", session.getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME)); //확인용 로깅
  return "redirect:/tasks";
 }
}

메시지 관리 파일 만들기

  • 디폴트 파일인 messages.properties에 한국어 메시지를, messages_en.properties에 영어 메시지를 적었다.
  • 테스트코드에서 MessageSourcegetMessage()에서도 Thymeleaf 템플릿에서도 모두 잘 출력되었다.

적용하기

<li><a href="/international?lang=ko">한국어</a></li>
<li><a href="/international?lang=en">English</a></li>
  • 파라미터를 통해 언어 정보를 전달하고 컨트롤러에서 그 정보를 받아 HttpSession의 로케일 정보를 변경해주었다.
  • 로깅을 통해 값이 잘 설정되었는지도 확인했다.

더 간편한 방법 - Spring Interceptor 이용

WebMvcConfigurer 인터페이스의 LocaleChangeInterceptor를 사용하면 로케일을 처리하는 컨트롤러 코드 없이 더 간단하게 로케일을 변경할 수 있다.

  • WebMvcConfigurer는 스프링 MVC의 기본 설정을 변경하거나 추가를 돕는 인터페이스이다.
  • Spring Interceptor란 클라이언트의 HTTP 요청을 컨트롤러에 넘겨지기 전에 가로채서(intercept) 특정 작업을 수행해주는 클래스이다. 그러니까 LocaleChangeInterceptor는 요청이 컨트롤러에 도달하기 전에 데이터를 가로채서 로케일을 변경해주는 것이다.

빈 설정하기

@Configuration
public class LocaleConfig implements WebMvcConfigurer {

 @Bean
 public SessionLocaleResolver localeResolver() {...}

 @Bean
 public LocaleChangeInterceptor localeChangeInterceptor() {
  LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
  localeChangeInterceptor.setParamName("lang");
  return localeChangeInterceptor;
 }

 @Override
 public void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(localeChangeInterceptor());
 }
}
  • LocaleConfigWebMvcConfigurer 인터페이스를 구현하도록(implements) 한다.
  • LocaleChangeInterceptor 빈을 추가해준다.
    • ParameterName의 기본값은 “locale”이다.
    • 언어 정보만 넘길 것이기 때문에 setParameterName()을 통해 “lang”으로 변경해주었다. (기본값 그대로 써도 상관없다.)
  • addInterceptors(): Interceptor를 InterceptorRegistry에 추가해준다. (스프링 인터셉트를 사용하기 위해서는 레지스트리에 추가해야 한다. addInterceptor() 메서드는 인터페이스에서 상속받아 사용하는 것이므로 @Override 애노테이션을 달아준다.)

컨트롤러 코드 정리하기

@Controller
public class configController {

 @GetMapping("/international")
 public String changeLocale() {
  return "redirect:/tasks";
 }
}
  • 이제 session.setAttribute()와 같은 처리는 필요없다. 컨트롤러는 리다이렉팅만 하고 “lang” 파라미터를 받아서 세션 레벨에서 로케일을 변경하는 작업은 Interceptor가 알아서 해준다.

🔗 References

연관 포스팅

0개의 댓글