[Springboot] 쿠키를 이용한 다국어 처리 (i18n)

Bobby·2021년 10월 14일
2

즐거운 개발일지

목록 보기
13/22
post-thumbnail

Preview

  • 국제화 -> internationalization -> i18n
  • 스프링의 MessageSource를 이용하여 언어별 페이지를 쉽게 구현할 수 있다!
  • 쿠키의 값을 이용하여 언어 정보를 받아와 처리한다.

다국어 처리하기

  • springboot 2.5.5
  • dependency
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'

1. 프로젝트 구조


2. messages.properties

  • 먼저 각 언어별로 사용할 메시지를 작성한다.
  • 따로 설정하지 않을 경우 스프링부트는 messages.properties 들을 찾는 기본 경로는 resources/ 이다.
  • messages{언어코드}.properties(또는 messages{언어코드}_{국가코드}) 형태로 만든다.
  • {0}, {1}, .. 로 인자를 받아 동적으로 메시지를 작성 할 수 있다.

messages_en.properties

language = english
welcome = Hello, {0}

messages_kr.properties

language = 한글
welcome = 안녕? {0}
  • 메시지 파일을 여러개 만들 경우 Resource Bundle로 자동으로 묶인다.

3. I18nConfig.java

  • 스프링 부트의 기본 설정들을 변경하기 위해 빈으로 등록한다.
@Configuration
public class I18nConfig implements WebMvcConfigurer {

    @Bean
    public LocaleResolver localeResolver() {

        CookieLocaleResolver resolver = new CookieLocaleResolver();
        resolver.setDefaultLocale(Locale.getDefault());
        resolver.setCookieName("lang");
        return resolver;
    }

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

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:/i18n/messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
}

MessageSource

  • 스프링이 작성한 언어 리소스들을 사용할 수 있게 등록, 설정하는 클래스.
    @Bean
    public MessageSource messageSource() {
        // 지정한 시간마다 다시 리로드 하도록 한다.
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        // 언어 리소스들이 있는 경로를 지정한다.
        messageSource.setBasename("classpath:/i18n/messages");
        messageSource.setDefaultEncoding("UTF-8"); // 인코딩
        messageSource.setCacheSeconds(10 * 60); // 리로드 시간
        return messageSource;
    }

LocaleResolver

  • 스프링이 클라이언트의 언어,국가 정보를 인식하게 하는 클래스.
  • AcceptHeaderLocaleResolver : Http 헤더의 Accept-Language의 값을 사용한다. (기본값)
  • CookieLocaleResolver : 쿠키의 값을 저장하여 사용한다.
  • SessionLocaleResolver : 세션에 값을 저장하여 사용한다.
  • FixedLocaleResolver : 요청과 관계없이 default locale 사용한다.
  • CookieLocaleResolver를 사용하였고 쿠키이름을 lang으로 설정했다.
  • 값이 없을 경우에는 기본값(현재 동작하는 컴퓨터 환경의 Locale)을 사용하도록 설정.
    @Bean
    public LocaleResolver localeResolver() {

        CookieLocaleResolver resolver = new CookieLocaleResolver();
        resolver.setDefaultLocale(Locale.getDefault());
        resolver.setCookieName("lang");
        return resolver;
    }
  • 쿠키관련 여러가지 설정이 가능하다.

LocaleChangeInterceptor

  • Locale 값이 변경되면 인터셉터가 동작한다.
  • url의 query parameter에 지정한 값이 들어올 때 동작한다.
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");
        return interceptor;
    }

인터셉터 등록

  • LocaleChangeInterceptor 를 스프링 컨테이너에 등록한다.
  • WebMvcConfigurer 를 상속받고 addInterceptors를 오버라이딩 한다.
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

4. 컨트롤러 및 뷰

@Controller
public class TestController {

    @GetMapping("/test")
    public String test() {
        return "test";
    }
}
  • 템플릿 엔진으로는 타임리프를 사용했다.
  • #{key} 의 형태로 사용할 수 있다.
  • 인자를 받아서 쓰는 경우에는 #{key('arg1', 'arg2', ... )} 형태로 사용할 수 있다.
    <h1 th:text="'i18n Test'"></h1>

    <h4 th:text="#{language}"></h4>
    <h4 th:text="#{welcome('kim')}"></h4>

5. 테스트


MessageSource 사용하기

  • MessageSource를 주입 받아서 코드에서 불러올 수 있다.
  • getMessage() 메소드를 이용한다.
@SpringBootTest
class MessageSourceTest {

    @Autowired
    MessageSource messageSource;

    @Test
    void messageSourceTest() {
        System.out.println(messageSource.getMessage("welcome", new String[]{"kim"}, Locale.ENGLISH));
        System.out.println(messageSource.getMessage("welcome", new String[]{"kim"}, Locale.KOREAN));
    }
}


코드

profile
물흐르듯 개발하다 대박나기

0개의 댓글