본문 바로가기

[Spring]메시지와 국제화

민이(MInE) 2023. 5. 12.
반응형

Inflearn의 김영한님의 스프링 MVC 2편 -백엔드 웹 개발 활용 기술 강의를 참고하여 작성한 내용입니다.

https://inf.run/vwMD

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

www.inflearn.com


 

👉메시지

만약 화면에 보이는 상품명, 가격, 수량 등, label에 있는 단어를 변경해야하는 상황이 생긴다면 HTML 파일에 메시지가 하드코딩 되어 있기 때문에 화면 수가 수십개 이상이라면 수십개의 파일을 모두 고쳐야 하는 상황이 생긴다. 이런 다양한 메시지를 한 곳에서 관리하도록 하는 기능을 메시지 기능이라고 한다.

 

messages.properties 라는 메시지 관리용 파일을 만든다.

item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량

 

HTML에서 해당 데이터를 key 값으로 불러 사용한다.

<label for="itemName" th:text="#{item.itemName}"></label>
<label for="itemName" th:text="#{item.itemName}"></label>

 

👉국제화

메시지에서 설명한 메시지 파일(messages.properties)을 각 나라별로 별도로 관리하면 서비스를 국제화 할 수 있다.

 

messages_en.properties

item=Item
item.id=Item IDitem.itemName=Item Name
item.price=price
item.quantity=quantity

 

messages_ko.properties

item=상품
item.id=상품 ID
item.itemName=상품명
item.price=가격
item.quantity=수량

 

영어를 사용해야 하는 상황이면 messages_en.propeties를 사용하고, 한국어를 사용해야 하는 상황이면 messages_ko.properties를 사용하게 하면 된다.

 

한국에서 접근한 것인지 영어에서 접근한 것인지 인식하는 방법은 HTTP accept-language해더 값을 사용하거나 사용자가 직접 언어를 선택하도록 하고, 쿠키 등을 사용해 처리한다.

 


 

👉스프링 메시지 소스 설정

메시지 관리 기능을 사용하기 위해 스프링이 제공하는 MessageSource를 스프링 빈으로 등록하면 되는데, MessageSource는 인터페이스이기 때문에 구현체인 ResourceBundleMessageSource를 스프링 빈으로 등록하면 된다. 스프링 부트는 MessageSource를 자동으로 스프링 빈으로 등록한다.

 

직접 등록하는 법

@Bean
public MessageSource messageSource() {
 	ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
 	messageSource.setBasenames("messages", "errors");
 	messageSource.setDefaultEncoding("utf-8");
 	return messageSource;
}

 

스프링 부트 사용시 메시지 소스를 아래와 같이 설정 가능하다.

application.properties

spring.messages.basename=messages,config.i18n.messages

 

👉메시지 파일 생성

메시지 파일은 아래와 같이 생성 가능하다

/resources/messages.properties

hello=안녕
hello.name=안녕 {0}

 

👉스프링 메시지 소스 사용

MessageSource 인터페이스를 사용해 코드를 포함한 일부 파라미터로 메시지를 읽어오는 기능을 사용 가능하다.

 

MessageSource

public interface MessageSource {
String getMessage(String code, @Nullable Object[] args, @Nullable String 
defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws
NoSuchMessageException;

MessageSourceTest

package hello.itemservice.message;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.MessageSource;
import static org.assertj.core.api.Assertions.*;

@SpringBootTest
public class MessageSourceTest {
 	@Autowired
 	MessageSource ms;
 	@Test
 	void helloMessage() {
 		String result = ms.getMessage("hello", null, null);
 		assertThat(result).isEqualTo("안녕");
 	}
}

ms.getMessage("hello", null, null)

  • code: hello
  • args: null
  • locale: null

locale 정보가 없으면 basename에서 설정한 기본 이름 메시지 파일을 조회한다. basename으로 messages를 지정해서 messages.properties파일에서 데이터를 조회한다.

 

 

MessageSourceTest - 메시지가 없는 경우, 기본 메시지

@Testvoid notFoundMessageCode() {
 	assertThatThrownBy(() -> ms.getMessage("no_code", null, null))
 		.isInstanceOf(NoSuchMessageException.class);
}

@Test
void notFoundMessageCodeDefaultMessage() {
 	String result = ms.getMessage("no_code", null, "기본 메시지", null);
 	assertThat(result).isEqualTo("기본 메시지");
}

 

MessageSourceTest - 매개변수 사용

@Test
void argumentMessage() {
 	String result = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
 	assertThat(result).isEqualTo("안녕 Spring");
}

 

MessageSourceTest - 국제화 파일 선택1

@Test
void defaultLang() {
 	assertThat(ms.getMessage("hello", null, null)).isEqualTo("안녕");
 	assertThat(ms.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
}

 

MessageSourceTest - 국제화 파일 선택2

@Test
void enLang() {
 	assertThat(ms.getMessage("hello", null,
	Locale.ENGLISH)).isEqualTo("hello");
}

 

👉웹 애플리케이션에 메시지 적용해보기

messages.properties

label.item=상품
label.item.id=상품 ID
label.item.itemName=상품명label.item.price=가격
label.item.quantity=수량

page.items=상품 목록
page.item=상품 상세
page.addItem=상품 등록
page.updateItem=상품 수정

button.save=저장
button.cancel=취소

타임리프로 메시지 적용

 

#{...}를 사용해 스프링의 메시지를 조회 가능하다. 

ex) #{label.item}

 

페이지 이름에 적용

<h2>상품 등록 폼</h2>
	<h2 th:text="#{page.addItem}">상품 등록</h2>

 

레이블에 적용

<label for="itemName">상품명</label>
	<label for="itemName" th:text="#{label.item.itemName}">상품명</label>
	<label for="price" th:text="#{label.item.price}">가격</label>
	<label for="quantity" th:text="#{label.item.quantity}">수량</label>

 

버튼에 적용

<button type="submit">상품 등록</button>
	<button type="submit" th:text="#{button.save}">저장</button>
	<button type="button" th:text="#{button.cancel}">취소</button>

 

👉웹 애플리케이션에 국제화 적용해보기

messages_en.properties

label.item=Itemlabel.item.id=Item ID
label.item.itemName=Item Name
label.item.price=price
label.item.quantity=quantity

page.items=Item List
page.item=Item Detail
page.addItem=Item Add
page.updateItem=Item Update

button.save=Save
button.cancel=Cancel

위 파일만 만들어주면 국제화 작업은 거의 끝이다.

 

웹으로 확인하는 방법은 아래와 같다.

 

크롬 부라우저 -> 설정 -> 언어

 

옆에 점 세개를 눌러 영어를 맨 위로 올려주면 된다.

 

다음과 같이 영어로 적용된 것을 볼 수 있다.

 

반응형

댓글