개요
HTML에 문구를 하드 코딩해버리면 기존 문구를 일괄적으로 변경해야 할 때 혹은 한글을 모르는 외국인들에게도 서비스를 제공하고 싶을 때 일일이 변경해야 하기 때문에 상당히 곤란한 상황에 직면하게 됩니다.
따라서, HTML에 하드코딩하는 대신 다양한 메시지를 한 곳에서 관리하는 메시지 기능을 익혀놓으면 실무에서 유용하게 사용할 수 있습니다.
메시지 기능 설정
메시지 기능을 사용하기 위해서는 MessageSource라는 스프링 빈을 등록해주면 되고 이는 인터페이스이기 때문에 구현체인 ResourceBundleMessageSource 빈을 등록해주면 됩니다. (스프링 부트에서는 자동으로 등록)
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages", "[원하는 파일명]");
messageSource.setDefaultEncoding("utf-8");
return messageSource;
}
* basenames: 설정 파일의 이름 등록 (messages로 지정하면 messages.properties 파일을 읽어서 사용)
* 국제화 기능 적용을 위해서는 messages_en.properties와 같이 파일명 마지막에 언어 정보 추가 (국제화 파일이 없을 경우 디폴트인 message.properties 사용)
* 여러 파일을 한번에 지정할 수 있으며 파일명도 원하는 대로 가능하지만 통상적으로 messages 사용 (스프링 부트의 디폴트 파일명)
* Spring Boot에서는 src/main/resources/messages.properties를 찾았을 때 자동으로 MessageSource 빈을 등록
MessageSource 인터페이스 분석
MessageSource 인터페이스를 확인하면 messages.properties에서 메시지를 읽어오는 기능을 제공하는 것을 확인할 수 있습니다.
또한, 국제화 기능을 사용할 때는 HTTP accept-language 헤더 값 혹은 locale 정보를 기반으로 국제화 파일을 선택하는데 Locale이 en_US의 경우 messages_en_US.properties 파일을 찾고 없을 경우 messages_en.properties 파일을 찾아보고 그래도 없으면 디폴트 파일인 messages.properties 파일에서 찾습니다.
간단하게 몇 가지 예시를 들어보겠습니다.
messages.properties
hi=안녕
hi.nickname=안녕 {0}
messages_en.properties
hi=hi
hi.nickname=hi {0}
예시 코드
* 코드로 예시를 보여드렸지만 제 경험상 코드로 불러오는 경우는 거의 없고 타임리프에 th:text 기능을 통해 직접 지정하는 경우가 대다수였습니다.
스프링 언어 선택 방법
스프링은 앞선 예시처럼 Locale 값을 보고 언어를 선택하기도 하지만 대부분 HttpServletRequest의 Accept-Language 헤더 값을 보고 언어를 선택합니다.
스프링은 Locale 선택 방식을 변경할 수 있도록 LocaleResolver 인터페이스를 제공하며 스프링 부트는 기본적으로 Accept-Language를 활용하기 때문에 AcceptHeaderLocaleResolver를 디폴트로 사용합니다.
Accept-Language가 하나일 경우에는 간단하지만 상황에 따라 아래와 같이 복잡한 상황이 발생하기도 합니다.
- 원하는 상황: 가급적 한국어를 원하지만 불가능한 경우 영어 그 것마저 불가능하다면 불어
- 해결책: 이런 경우에는 Accept-Language 헤더에 우선순위인 Quality Values 값을 사용해야 합니다.
- 값이 클수록 우선순위가 높은 것이며 범위는 0 ~ 1 (생략할 경우 1)
- 원하는 상황에 맞는 예시: Accept-Language: ko-KR; ko;q=0.9, en-US;q=0.8, en;q=0.8, fr;q=0.3
메시지 기능을 사용하면서 아쉬웠던 부분
메시지 파일이 하나의 공통 파일이다 보니 다수의 개발자가 여러 브랜치에서 나누어 작업하고 코드를 병합할 때 매번 messages.properties와 messages_en.properties 충돌이 나 merge conflict를 해결하는 번거로움이 발생하고 있습니다.
위 문제를 해결하기 위해서는 파트별로 messages.propreties를 분리해야 할 것 같은데 개발기간이 타이트한 지금으로서는 해결하기 어려운 문제처럼 보입니다.
이러한 아쉬움이 있더라도 HTML 하드코딩보다는 훨씬 괜찮은 방식인 것은 확실합니다!
출처
인프런 스프링 MVC 2편 (김영한 강사님)
'Spring' 카테고리의 다른 글
[SpringBoot] Validation 간단 정리 - 2 (Bean Validation) (0) | 2021.07.25 |
---|---|
[SpringBoot] Validation 간단 정리 - 1 (BindingResult, Validator) (6) | 2021.07.16 |
HttpMessageConverter 간단 정리 (0) | 2021.06.11 |
Spring MVC 구조 정리 (0) | 2021.06.09 |
클라이언트에서 서버로 HTTP 요청 메시지 보내는 방법 (0) | 2021.06.02 |