성실한 사람이 되자

성실하게 글쓰자

This is spear

JAVA_SPRING

스프링을 이용한 메시지 기능과 메시지 기능 국제화(HTTP 헤더 값을 이용한 방법과 파라미터를 이용한 방법)

Imaspear 2022. 1. 22. 15:58
728x90

스프링을 이용한 메시지 기능과 메시지 기능 국제화

메시지 기능

메시지 기능은 다양한 메시지를 한 곳에 관리하도록 하는 기능을 말한다. 여러 화면에 보이는 단어들을 일일이 변경하려면 모든 파일들을 다 들어가야하지만, 메시지 기능을 이용하면 한 곳에 관리해 보다 쉽게 변경하고 관리할 수 있다.

국제화

메시지 기능을 각 나라별로 별도로 관리할 수 있도록 국제화를 지원하는 기능이다. 특정한 값을 넘겨받아 어디에 오는 나라인지 확인하면 그 나라에 따라 언어를 지원하는 방법이다. 만약 지원하지 않는 나라에서 접근한다면, 기본 설정으로 된 언어로 파일이 전송이 된다. 어디서 접근한 건지 알 수 있는 방법은 대략 세가지가 존재한다.

  1. HTTP accept-language 해더 값
  2. 사용하거나 사용자가 직접 언어를 직접 선택
  3. 쿠키 등을 사용해서 처리

스프링은 기본적인 메시지와 국제화 기능 모두 제공하고, 타임리프도 스프링이 제공하는 메시지와 국제화 기능을 편리하게 통합해서 제공한다.

메시지 기능 설정 파일을 이용해 직접 등록 하기 (HTTP 헤더 값 이용)

특정한 스프링 빈 설정 파일을 생성해 안에 메시지 소스를 구현한 구현체를 이용해 파일들을 관리하면 된다.

  • WebConfig.class
    setBasenames() 메서드를 이용해 메시지가 들어갈 프로퍼티의 이름을 설정하고, setDefaultEncoding() 메서드를 이용해 인코딩한다. utf-8로 하지 않으면 한국어가 깨진다.

      @Configuration
      public class WebConfig {
          @Bean
          public MessageSource messageSource() {
              ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
              messageSource.setBasenames("register-message");
              messageSource.setDefaultEncoding("utf-8");
              return messageSource;
          }
      }

아래 프로퍼티의 이름을 보면 패턴이 존재한다. setBasenames()를 이용해 register-message라는 이름을 등록했는데, 해당 등록된 이름에 *_en, *_de, *_ko 이런 식으로 등록을 하면 해당 나라에서 접근할 때 나라에 맞는 메시지가 출력이 된다.

  • register-message.properties

      page.main=메인 페이지
      page.detail=상세 페이지
    
      comment.hello=안녕하세요.
      comment.greet=반갑습니다.
      #name = spear
      comment.introduce=저의 이름은 {0}입니다.
      #studying spring framework
      comment.stuyding=현재는 {0}를 공부하고 있습니다.
      comment.project.detail=이 프로젝트는 메시지와 국제화 기능을 테스트하기 위해 제작되었습니다.
  • register-message_de.properties

      page.main=Hauptseite
      page.detail=Detaillierte Seite
      comment.hello=Hallo.
    
      comment.greet=Schön, Sie kennenzulernen.
      #name = spear
      comment.introduce=Mein Name ist {0}.
      #studying spring framework
      comment.stuyding=Ich studiere derzeit das {0}.
      comment.project.detail=Dieses Projekt wurde entwickelt, um Nachrichten und Internationalisierungsfunktionen zu testen.
  • register-message_en.properties

      page.main=Main page
      page.detail=Detail page
    
      comment.hello=Hello
      comment.greet=Nice to meet you.
      #name = spear
      comment.introduce=My name is {0}.
      #studying spring framework
      comment.stuyding=Currently, I am studying {0}.
      comment.project.detail=The project was designed to test messages and internationalization functions.
  • register-message_ko.properties

      page.main=메인 페이지
      page.detail=상세 페이지
    
      comment.hello=안녕하세요.
      comment.greet=반갑습니다.
      #name = spear
      comment.introduce=저의 이름은 {0}입니다.
      #studying spring framework
      comment.stuyding=현재는 {0}를 공부하고 있습니다.
      comment.project.detail=이 프로젝트는 메시지와 국제화 기능을 테스트하기 위해 제작되었습니다.
  • ViewController.class
    위 메시지 기능과 국제화 기능을 보여주기 위해 간단한 컨트롤러를 생성했다.
```java
@Controller
public class ViewController {

    @ModelAttribute("user")
    public User user() {
        return new User("spear", "Spring framework");
    }

    @RequestMapping()
    public String index() {
        return "web/index";
    }

    @RequestMapping("/main")
    public String main() {
        return "web/main";
    }

    @RequestMapping("/details")
    public String details() {
        return "web/details";
    }
}
```
  • index.html

    타임리프를 이용해 html을 생성했다. 타임리프는 스프링이 제공하는 메시지와 국제화 기능을 편리하게 통합해서 제공하기 때문에 사용했다.

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <button th:text="#{page.main}" th:onclick="|location.href='@{/main}'|">메인 페이지</button>
      <button th:text="#{page.detail}" th:onclick="|location.href='@{/details}'|">상세 페이지</button>
      </body>
      </html>
  • main.html

      <!DOCTYPE html>
      <html xmlns:th="http://www.thymeleaf.org">
      <head>
          <meta charset="UTF-8">
          <title th:text="#{page.main}">메인</title>
      </head>
      <body>
          <h1 th:text="#{page.main}">메인</h1>
          <p th:text="#{comment.hello}"></p>
          <p th:text="#{comment.greet}"></p>
          <p th:text="#{comment.introduce(${user.userName})}"></p>
          <button th:text="#{page.detail}" th:onclick="|location.href='@{/details}'|">상세 페이지</button>
      </body>
      </html>
  • details.html

      <!DOCTYPE html>
      <html xmlns:th="http://www.thymeleaf.org">
      <head>
          <meta charset="UTF-8">
          <title th:text="#{page.detail}">상세</title>
      </head>
      <body>
          <h1 th:text="#{page.detail}">상세</h1>
          <p th:text="#{comment.greet}"></p>
          <p th:text="#{comment.introduce(${user.userName})}"></p>
          <p th:text="#{comment.stuyding(${user.studying})}"></p>
          <p th:text="#{comment.project.detail}"></p>
    
      <button th:text="#{page.main}" th:onclick="|location.href='@{/main}'|">메인 페이지</button>
      </body>
      </html>

Accept-Language 값을 주지 않았을 때

Accept-Language 값이 en일 때

Accept-Language 값이 de일 때

스프링 설정 파일에서 설정한 메시지 기능을 통해 국제화한 모습을 볼 수 있다. 아래는 설정 파일에서 설정하지 않고 메시지 기능을 사용하는 방법을 적었다.

스프링 부트가 자동 등록하는 방법 (HTTP 헤더 값을 이용한 방법)

일단 WebConfig를 삭제했다. 수동 등록과 스프링 부트를 이용해 등록하는 방법을 동시에 사용하면 오류가 나온다.

  • application.properties
    프로퍼티에 아래와 같이 설정하면 된다.

      spring.messages.basename=register-message

마찬가지로 잘 동작한다.

위 두개의 방법들은 Accept-Laungage라는 값을 이용해 국제화를 설정했지만 아래는 파라미터를 통해 국제화를 해봤다.

LocaleResolver( 파라미터를 이용해 언어를 변경하는 방법 )

WebConfig와 같은 설정 파일을 다시 생성해 LocaleResolver를 직접 구현한 구현체를 넘겨줬다. 해당 구현체에서는 파라미터 값중 lang이라는 파라미터의 문자열 값을 가져와 언어를 변경할 수 있도록 설정했다.

파라미터 이용

  • ViewController

      @Controller
      public class ViewController {
    
          @ModelAttribute("user")
          public User user() {
              return new User("spear", "Spring framework");
          }
    
          @RequestMapping()
          public String index(@RequestParam(name = "lang") String lang) {
              return "web/index";
          }
    
          @RequestMapping("/main")
          public String main(@RequestParam(name = "lang") String lang) {
              return "web/main";
          }
    
          @RequestMapping("/details")
          public String details(@RequestParam(name = "lang") String lang) {
              return "web/details";
          }
    
      }
  • WebConfig

      @Configuration
      public class WebConfig{
    
          public LocaleResolver theLocaleResolver = new LocaleResolver() {
              @Override
              public Locale resolveLocale(HttpServletRequest request) {
                  String lang = request.getParameter("lang");
                  return new Locale(lang);
              }
    
              @Override
              public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
    
              }
          };
    
          @Bean
          public LocaleResolver localeResolver() {
              return theLocaleResolver;
          }
    
      }

파라미터 값을 넘겨줬을 때 바뀌는 모습을 볼 수 있다.

그 외 세션과 쿠키 등을 이용해 국제화를 할 수 있다. 그렇게 되면 해당 유저 데이터에 저장된 나라별로 값을 변경할 수 있는 것을 볼 수 있다.