1. MessageSource
국제화 서비스를 위해서는 사용자 언어에 맞는 페이지가 번역되어 보여져야 합니다.
그런데 서비스 되는 언어마다 html 파일을 작성하여, 요청 언어에 따라 응답 페이지를 분기시키는 것은 매우 비효율적이고, 유지보수를 어렵게 만듭니다.
- ko : main_ko.html
- jp : main_jp.html
- cn : main_cn.html
- ...
2. 구현하기
프로젝트 구조
1) 컨트롤러
src/main/java/com/victolee/i18n/controller/i18nController.java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class i18nController {
@GetMapping("/test")
public String test() {
return "test";
}
}
2) 템플릿
src/main/resources/templates/test.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>i18n 테스트</h1>
<p th:text="#{product}"></p>
<p th:text="#{product.category}"></p>
</body>
</html>
- thymeleaf에서 MessageSource의 메시지를 가져오기 위해서는 #{속성명}을 작성해주면 됩니다.
- 즉, product, product.category는 messages.properties 파일에서 언어별로 텍스트를 정의해줄 것입니다.
3) messages.properties
다음으로 messages_{언어코드}_{국가코드}.properties 파일에 번역 텍스트를 작성해줍니다.
messages.properties 파일은 사용자 언어 환경에 맞는 properties 파일이 없을 경우, 기본 값으로 보여지는 파일입니다.
각 properties 파일에서 텍스트를 작성하기 전에 IDE에서 *.properties 파일의 인코딩을 UTF-8로 설정해주도록 합니다.
그렇지 않으면 한글 등의 문자가 깨짐 현상이 발생합니다.
src/main/resources/messages.properties
product=some product
product.category=some category
src/main/resources/messages_en_US.properties
product=us product
product.category=us category
src/main/resources/messages_ko_KR.properties
product=한국 상품
product.category=한국 카테고리
각각의 파일은 이렇게 bundle로 묶여지면 손쉽게 관리할 수도 있습니다.
여담이지만.. properties 파일이 아닌 yml을 사용하고 싶은데, 현재 다른 포맷을 지원하고 있지 않다고 합니다. ( 참고 )
4) application.java
src/main/java/com/victolee/i18n/I18nApplicationjava
package com.victolee.i18n;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
@SpringBootApplication
public class I18nApplication {
public static void main(String[] args) {
SpringApplication.run(I18nApplication.class, args);
}
/*
* 사용자 언어 환경을 설정해주기 위한 bean 설정
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(Locale.US); // <---- 해당 값을 수정하여 언어 결정
return sessionLocaleResolver;
}
}
- 테스트를 하려면 사용자 언어 환경을 셋팅해줘야 하기 때문에 bean을 추가합니다.
- 즉, Locale.US로 설정했으면 messages_en_US.properties에 작성된 텍스트가 보여집니다.
- 아래의 테스트는 해당 값을 바꿔가며 진행됩니다.
5) 테스트
Locale.US로 설정
messages_en_US.properties 파일에 명시된 텍스트가 의도된대로 노출됩니다.
Locale.JAPAN로 설정
messages_ja_JP.properties 파일은 작성하지 않았기 때문에, 기본 값인 messages.properties 파일의 텍스트가 보여질 것이라 예상할 수 있습니다.
그러나 messages_ko_KR.properties 텍스트가 노출되었는데, 이는 spring.messages.fallback-to-system-locale 설정과 관련이 있습니다.
기본 값이 false이므로 messages_ja_JP.properties 파일을 찾지 못했을 경우, 시스템의 locale을 따라가게 됩니다.
즉, messages_ko_KR.properties 에서 텍스트를 가져오는 것이죠.
( 설정에 대한 내용은 뒤에서 다루겠습니다. )
같은 상황에서 spring.messages.fallback-to-system-locale = false 를 해주면 아래와 같이 messages.properties에서 텍스트를 가져옵니다.
6) 설정
예제에서는 다루지 않았지만, MessageSource와 관련된 설정들을 application.yml 파일에 작성할 수 있습니다. ( 참고 )
key |
기본값 |
설명 |
spring.messages.always-use-message-format |
false |
MessasgeFormat을 전체 메시지에 적용할 것인지 여부 |
spring.messages.basename |
messages |
message 파일을 여러개 사용할 경우 콤마로 구분해서 여러개의 basename을 설정할 수 있다. |
spring.messages.cache-duration |
|
캐시 주기 설정, 기본 값 forever |
spring.messages.encoding |
UTF-8 |
인코딩 방식 |
spring.messages.fallback-to-system-locale |
true |
감지된 locale에 대한 파일이 없는 경우,
|
spring.messages.use-code-as-default-message | false | 메시지를 찾지 못했을 때, 예외 처리 대신 메시지 코드를 그대로 반환 |
이상으로 다국어를 처리하는 방법에 대해 알아보았습니다.
[ 참고 자료 ]
https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html
'웹 프로그래밍 > SpringBoot' 카테고리의 다른 글
[SpringBoot] Kafka 연동하기 (3) | 2020.11.15 |
---|---|
[SpringBoot] 이메일 전송 ( JavaMailSender, MimeMessageHelper ) (9) | 2020.03.01 |
[SpringBoot] Swagger - API Docs 자동화 (7) | 2020.02.26 |
[SpringBoot] 에러 페이지 처리하기 (0) | 2020.02.22 |
[SpringBoot] 게시판 (5) - AWS EC2에 배포하기 (feat. AWS RDS) (24) | 2020.02.21 |
[SpringBoot] AWS S3 연동 (2) - 파일 조작 및 Cloud Front (3) | 2020.02.02 |
[SpringBoot] AWS S3 연동 (1) - 파일 업로드 기본 (AmazonS3ClientBuilder) (15) | 2020.01.27 |