스프링/4. 스프링 MVC-2

24. 메시지, 국제화

sdafdq 2023. 8. 27. 13:37

메시지는 예를 들어,

우리가 상품명 : , 이런 단어들이 있다고 치자.

근데 만약 저걸 "상품이름 : " 이렇게 고치고 싶다면, 웹페이지가 수십개라면 힘들다. 

 

일종의 공통 이름들을 message.properties라는 파일에 정의해둬서 변수처럼 사용할 수 있다.

양식은 #{클래스이름.변수이름}

 

 

국제화

위의 저걸 다 영단어로 바꾸면 끝.

message_en.properties

message_ko.properties

 

 

이 기능은 스프링에서 제공하는 추상체 MessageSource 기능을 사용하면 된다. 저걸 Bean에 등록해서 쓰면 된다.

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

이런 식이다.

역시 직접 만들때는 클래스, 구현체를 쓰고,

setBasename("messages") 저렇게 하면 messages.properties라는 파일을 읽는다.

참고로 setBasenames("meslsages", "errors") 이렇게 names로 하면 여러 개 넣을 수도 있다.

문자에 대한 인코딩 설정해주고,

return해주면 빈 호출 시 저걸 리턴해준다.

 

근데 스프링 부트 쓰면 저거 자동으로 해줘서 안써줘도 된다.

 

 

만약 스프링부트를 이용해서 자동으로 쓰고 싶다면, 

application.properties에 메시지에 대한 파일을 명시해 주면된다.

 

spring.messages.basename=messages

이것또한 기본값으로 따로 명시 안해줘도 자동으로 인식된다.

 

resources/에 messages라는 문자열을 가진 properties 파일을 인식하는 것이므로,

message_en.properties 이런 것 들도 다 포함이 된다.

 

 

messages.properties

 

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

 

이렇게 등록 해놨다. {0} 이건 인자. 인자의 인덱스 인 듯

 

 

messages_en.properties

 

hello=hello
hello.name=hello {0}

 

이렇게 등록해놨다.

 

기본값은 messages이고 클라이언트의 요청에 따라 en을 쓸지 등 결정한다. 

 

 

@SpringBootTest
public class MessageSourceTest {
    @Autowired
    MessageSource ms;

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

테스트.

참고로 ?? 이렇게 나올 수 있는데, 설정에서 파일 인코딩 들어가면 문자셋을 설정할 수 있는데 거기서 .properties의 설정을 utf-8로 해놔야 한다. 그리고 다시 messages.properties 확인해야 한다.  아마 문자셋이 안 맞는 상태에서 변경되어서 제대로 못 읽어 ?? 이렇게 바뀌었을 수도 있다.

 

그냥 애초에 모두 utf-8로 설정해 놓고 시작하는게 좋을 듯 하다.

 

ms.getMessage("키", 인자, 로컬) 이다.

로컬에 null이니 기본 messages.properties에서 가져옴.

 

 

 

 

@Autowired

MessageSource ms;

이거는 스프링이 자동으로 messages.properties를 빈으로 등록해 놓으니 알아서 의존성 주입이 된다.

 

 

 

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

일부로 이상한 코드 찾아봄.

assertThatThrownBy 이거는 저 () -> 이곳

이곳에서 뭐 하면 에러를 던진다는 거임.

.isInstanceOf(에러.class)

 

저기의 결과? 그러니까 나온 에러가 NoSuchMessageException.class의 객체인지 확인.

 

 

 

@Test
void notFoundMessageCodeDefaultMessage(){
    String result = ms.getMessage("strange_code", null, "Default Message", null);
    assertThat(result).isEqualTo("Default Message");
}

이렇게 로컬 전에 기본 메시지 설정 가능

 

 

 

인자

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

인자는 특이하게 new Object[]{"Spring", "hello"} 등 이렇게 오브젝트 배열로 넘겨야 함.

                                                      0           1

 

 

 

 

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

Locale.언어로 로컬 구분.

Locale.ENGLISH 이렇게 하면

_en 이런거 알아서 찾아서 읽어 주는 듯.

'스프링 > 4. 스프링 MVC-2' 카테고리의 다른 글

26. 검증  (0) 2023.08.27
25. 메시지, 국제화 적용  (0) 2023.08.27
23. 셀렉트 버튼  (0) 2023.08.27
22. 라디오버튼  (0) 2023.08.27
21. 멀티 체크박스  (0) 2023.08.27