3. 메시지, 국제화

ChoiJaewoo·2026년 2월 2일

Spring MVC 2편

목록 보기
3/10

만약, 화면의 문구로 출력된 “상품명” 을 “상품 이름” 으로 모두 수정하고자 한다.

그렇다면, 모든 html 파일의 “상품명” 을 모두 찾아서 모두 수정해야 한다. 매우 번거롭고 힘들고 실수가 발생할 수 있다. → 메시지

왜? 지금은 하드코딩 되어 있기 때문이다.

또는, 기본 locale 설정이 en 인 유저가 사이트에 접근하면, 영어로. ko 인 유저가 사이트에 접근하면, 한글로 랜더링 해주고 싶을 때 어떻게 해야 하나? → 국제화

message.properties 라는 메시지 관리용 파일을 만들고, 각 html은 파일의 데이터를 key 값으로 불러 사용하는 방식을 사용할 수 있다!

위의 두 문제는 “메시지”“국제화” 로 해결할 수 있고, 이를 스프링이 어떻게 지원하는지 코드를 통해 알아보자.

스프링 메시지 소스 설정

스프링은 메시지 관리 기능을 기본으로 제공한다.

메시지 관리 기능을 사용하려면, 스프링이 제공하는 MessageSource 를 스프링 빈으로 등록해야 한다.

이때, 스프링 부트를 사용하면, 스프링 부트가 자동으로 MessageSource를 스프링 빈으로 등록한다.

만약, 직접 Spring Bean에 등록하고자 한다면?

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

만약, 직접 application.properties 에 등록하고 싶다면?

application.properties

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

스프링 부트와 관련된 별도의 설정을 하지 않으면 messages 라 는 이름으로 기본 등록된다. 따라서 messages_en.properties , messages_ko.properties , messages.properties 파일만 등록하면 자동으로 인식된다.

메시지 파일 만들기

국제화 테스트를 위해서 messages_en 파일을 추가한다.

  • 기본값 : messages.properties (한글)
  • 영어 국제화에 사용 : messages_en.properties

스프링 메시지 소스 사용

결과적으로 메시지 source 라는 것이 스프링 빈에 등록되기 때문에, 이거를 가져다가 쓰기만 하면 된다.

MessageSource interface

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;
}

해당 인터페이스를 사용하는데, 이를 보면 일부 파라미터로 메시지를 읽어오는 기능을 제공한다.

messages.properties

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

messages_en.properties

hello=hello
hello.name=hello {0}

Test 를 통해 알아본다.

MessageSourceTest

메시징 테스트

@SpringBootTest
public class MessageSourceTest {
    @Autowired
    MessageSource messageSource;

    @Test
    void helloMessage() {
        String result = messageSource.getMessage("hello", null, Locale.KOREA);
        assertThat(result).isEqualTo("안녕");
    }

    @Test
    void notFoundMessageCode() {
        assertThatThrownBy(() -> messageSource.getMessage("no_code", null, null))
                .isInstanceOf(NoSuchMessageException.class);
    }

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

    }

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

국제화 테스트

@SpringBootTest
public class MessageSourceTest {
    @Autowired
    MessageSource messageSource;

    @Test
    void defalutLang() {
        assertThat(messageSource.getMessage("hello", null, null)).isEqualTo("안녕");
        assertThat(messageSource.getMessage("hello", null, Locale.KOREA)).isEqualTo("안녕");
    }
    @Test
    void enLang() {
        assertThat(messageSource.getMessage("hello", null, Locale.US)).isEqualTo("hello");
        assertThat(messageSource.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=취소

messages_en.properties 추가

label.item=Item
label.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

타임리프에서 메시지 적용하기

타임리프 메시지 표현식 “#{ … }" 를 사용하면, 스프링 빈에 등록된 메시지를 조회하여 사용할 수 있다.

예) 상품 이라는 이름을 조회하려면, “#{label.item}" 을 사용하면 된다.

Before : addForm.html

<h2>상품 등록 폼</h2>

After : addForm.html

<h2 th:text = "#{page.addItem}"></h2>

동일한 방법으로 나머지 항목도 수정해 준다.

만약, 파라미터를 사용하고 싶다면?

messages.properties 추가

testLabel = 상품 {0}
testList = 목록

items.html 적용

<h2 th:text="#{testLabel(#{testList})}">상품 목록 default value</h2>

웹 애플리케이션에 국제화 적용하기

messages_en.properties 에 적용한 것들을 영어로 랜더링해서 보여주자.

그러기 위해서 messages.properties 와 동일한 이름으로 값들을 만들어주면 된다.

웹 브라우저에서 설정 → 언어 → 영어를 맨 위로 하고 새로고침 해보자.

실행 결과


  • 서버의 새로고침 없이 바로 랜더링 됨을 알 수 있다.
  • 웹 브라우저의 언어 설정을 변경하면, Accept-Language 값이 변경된다.
  • 클라이언트는 이를 통해 서버에 기대하는 언어 정보를 담아 HTTP 요청 헤더를 만들고 이를 받은 서버는 그에 맞춰서 client 에게 랜더링 해 줄 수 있다.

0개의 댓글