[springmvc2]1. 메시지

이건회·2022년 9월 15일
0

springmvc

목록 보기
28/29

메시지

  • 만약 프로그램의 "상품명" 이라는 단어를 "상품이름"이라는 단어로 고쳐야 한다면 상당히 어렵다. 만약 화면이 수십개 이상이라면 이것을 전부 고쳐야 한다.

  • 이처럼 해당 html 파일에 메세지가 하드코딩 되어 있기 때문이다.

  • 따라서 이처럼 다양한 메세지를 한 곳에서 관리하도록 하는 기능을 메시지 기능이라 한다.

  • 메세지는 다음과 같이 관리할 수 있다.

//message.properties
item=상품 
item.id=상품 ID 
item.itemName=상품명 
item.price=가격 
item.quantity=수량
  • 위와 같은 message.properties라는 메시지 파일을 만든다고 가정하고
//addForm.html
<label for="itemName" th:text="#{item.itemName}"></label>
//editForm.html
<label for="itemName" th:text="#{item.itemName}"></label>
  • 각 html들은 다음과 같이 해당 데이터를 key로 불러서 사용한다.

국제화

  • 메세지에서 한 발 더 나아가서, 예를 들어 위와 같은 메세지 파일을 국제화 시켜 각 나라별로 별도로 관리해 한국에서는 한국어로, 미국에서는 영어로 뜨게 할 수 있다면 좋을 것이다.
//messages_en.properties
item=Item
item.id=Item ID
item.itemName=Item Name
item.price=price
item.quantity=quantity
//messages_ko.properties
item=상품
item.id=상품 ID 
item.itemName=상품명 
item.price=가격 
item.quantity=수량
  • 위처럼 영어를 사용하면 messages_en.properties, 한국어를 사용하면 messages_ko.properties를 사용하도록 하는 것이다.
  • 그럼 한국에서 접근했는지, 미국에서 접근했는지를 어떻게 판단할까? 답은 HTTP의 accept-language의 헤더 값을 사용하거나, 사용자가 직접 선택하거나, 쿠키를 사용하는 방법 등이 있다.
  • 스프링은 기본적인 메세지와 국제화 기능을 모두 지원한다.

스프링 메세지 소스 설정

  • 스프링의 메세지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource를 스프링 빈으로 등록하면 되는데, MessageSource는 인터페이스다. 따라서 구현체인 ResourceBundelMessageSource를 스프링 빈으로 등록하면 된다.
  @Bean
  public MessageSource messageSource() {
      ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
      messageSource.setBasenames("messages", "errors");
      messageSource.setDefaultEncoding("utf-8");
      return messageSource;
}
  • setBasenames를 통해 설정 파일의 이름을 지정한다. 하나를 지정할 수도, 여러 파일을 한번에 지정할 수도 있는데, 여기서는 messages, errors 둘을 지정을 지정했다.
  • messages로 지정하면 messages.properties 파일을 읽어서 사용한다.
  • 국제화 기능을 지정하려면, 위의 파일명을 지정할 때 messages_en.properties , messages_ko.properties 와 같이 파일명 마지막에 언어 정보를 주면된다. 만약 찾을 수 있는 국제화 파일이 없으면 messages.properties (언어정보가 없는 파일명)를 기본으로 사용한다.
  • 파일의 위치는 /resources/messages.properties 에 두면 된다
  • defaultEncoding 을 통해 인코딩 정보를 지정하는데, 보통 utf-8을 사용한다.

스프링 부트

  • 그런데 스프링 부트를 사용하면 위 설정 정보를 사용할 필요가 없다. application.properties에 다음과 같은 설정 정보만 박아넣으면 메세지 소스를 설정할 수 있다.
//application.properties
spring.messages.basename=messages,config.i18n.messages
spring.messages.basename=messages
  • 스프링 부트 메시지 소스 기본 값은 위와 같다. MessageSource 를 스프링 빈으로 등록하지 않고, 스프링 부트와 관련된 별도의 설정을 하지 않으면 messages 라는 이름으로 기본 등록된다. 따라서 Messages_en.properties , messages_ko.properties , messages.properties 파일만 등록하면 자동으로 인식된다.

메세지 파일 만들기

  • 이제 기본 값으로 사용하는 messages.properties와 messages_en.properties 파일을 만들어 주자. {0}을 통해 파라미터 값을 받을 수 있다. 파일명은 message가 아니라 messages인 점을 주의하자
  • 이제 어느 국가에서 접근하는지에 따라 자동으로 메세지를 구분해준다.

스프링 메세지 소스

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;
    }
  • MessageSource 인터페이스는 코드를 포함한 일부 파라미터로 메세지를 읽어오는 기능(getMessage)을 제공한다.

  • SpringBootTest를 사용하면 스프링 부트가 @Autowired를 통해 자동으로 MessageSource를 주입시켜 준다.
  • getMessage를 통해 hello 값에 해당하는 밸류를 조회하면 messages.properties에 지정한 대로 "안녕"이 조회되는 것을 확인할 수 있다
  • 현재 파라미터 값으로 code: hello, args: null, locale: null 값을 주었다.
  • locale 정보가 없으면 basename 에서 설정한 기본 이름 메시지 파일을 조회한다
  • basename 으로 messages 를 지정 했으므로 messages.properties 파일에서 데이터 조회한다

  • 다음과 같이 존재하지 않는 코드를 넣고 메세지를 조회하면 NoSuchMessageException 예외가 터진다.

  • 그러나 다음 처럼 defaultMessage 파라미터 값에 기본 메시지를 넣어주면 디폴트 메세지로 지정한 값을 출력해준다.

  • 이번엔 argument 값을 넘겨보겠다. Object를 통해 배열에 "Spring"을 넣어 치환해줄 수 있다.

  • Locale 값 설정을 통해 국제화 파일을 선택해보겠다. English를 지정하면 hello를 써도 KOREA와 다르게 hello가 출력되는 것을 확인할 수 있다

웹 어플리케이션에 메시지 적용하기

  • 위 메세지 설정 정보를 messages.properties에 추가한다.

  • 타임리프를 활용해 메세지 설정 정보의 파라미터 값을 넘겨주면 "상품 등록 폼"으로 html에 작성되어 있던 문구가 메시지 설정 정보에 의해 "상품 등록"으로 변경되었다.

  • 다른 html도 수정해주면 한꺼번에 반영된다.

hello.name=안녕 {0}
<p th:text="#{hello.name(${item.itemName})}"></p>
  • 파라미터는 다음과 같이 사용한다.

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

  • 국제화 설정 정보 적용을 위해 messages_en.properties에 설정 정보를 지정해준다.
  • 사실 이것으로 국제화 적용은 이미 끝났다. 이전에 html에 미리 #{...}을 통해 메세지 설정 정보를 지정했기 때문이다.
  • 그럼 한국어 설정 정보랑 영어 설정 정보랑 겹치는데 어떻게 선택하냐고? 아래처럼 하면 된다.

  • 크롬의 설정-언어 에서 영어를 맨 위로 올리면

  • 다음과 같이 messages_en.properties를 따르는 메세지 설정 정보가 자동으로 적용된다.

  • 이유는 언어 설정 값을 변경하는 순간 http 헤더의 Accept-Language 값이 변경되기 때문이다.

  • Accept-Language 는 클라이언트가 서버에 기대하는 언어 정보를 담아서 요청하는 HTTP 요청 헤더이다.

  • locale.english를 넘겨주는 것과 같다.

스프링의 국제화 메세지 선택

  • 위처럼 메세지 기능은 locale 정보를 알아야 언어를 선택할 수 있다.

  • 따라서 스프링도 locale을 알아야 하는데, 스프링은 기본적으로 http 헤더의 accept-language 값을 가지고 언어를 선택한다.

  • 또 스프링은 locale 선택 정보를 변경할 수 있는 인터페이스 또한 제공한다. 이를 LocaleResolver라 하며 스프링 부트는 기본으로 Accept-Language 를 활용하는 AcceptHeaderLocaleResolver 를 사용한다

profile
하마드

0개의 댓글