(JPA+Boot)메시지 국제화
스프링 프레임워크에서 메시지 국제화(i18n)를 구현하는 방법, 순수 스프링과 스프링 부트의 차이점, 핸들러 매핑과 인터셉터 활용 전략을 상세히 설명하는 가이드입니다.
메시지 국제화
순수스프링과 부트에서의 “메시지 국제화” 차이: 핸들러매핑, 인터셉터 이해
“디스패처 서블릿->HandlerMapping->인터셉터->컨트롤러 진입” (MVC라이프사이클 기억)
순수스프링은 xml에서 HandlerMapping지정 및 인터셉터 등록하면 해당 핸들러만 사용하다보니 문제없이 정상 동작하지만,
부트는 항상 여러 HandlerMapping을 자동등록(로그보니 5개정도?) 하기 때문에 순수스프링처럼 지정해버리면 다른 HandlerMapping들에 인터셉터가 등록이 되지 않는 문제가 발생한다.
- 부트는 스프링MVC패턴을 위한 디스패처서블릿 등등 여러가지를 자동으로 등록하는 특징
부트 사용하는 프로젝트의 경우 xml에
<mvc:interceptors>
패턴이나 부트가 권장하는 Java Config를 사용해서 “모든 핸들러매핑에 인터셉터를 등록”하자.
메시지 국제화 패턴은 여러 외국어를 지원하게 만들기 수월!!
-
application.properties
에spring.messages.basename=messages
를 추가!!
덕분에, MessageSource 빈을 부트가 자동 생성- 메시지 사용: JSP라면에서
<spring:message code="Login.form.id"/>
이런식으로 사용.(messages.propeties의 Login.form.id 매핑)
- 메시지 사용: JSP라면에서
-
message/meesages.properties, *_ko.properties, *_en.properties
를 세팅- 만약,
errors.properties
추가한다고 하면spring.messages.basename=messages, errors
이렇게 이어적으면 됨
- 만약,
-
메시지 국제화 방법은 LocaleChangeInterceptor빈과 LocaleResolver 빈을 만들어서 인터셉터 추가 설정을 해야지 적용 됩니다!(테스트는 URL?lang=en 이런식)
-
국제화 사용: url에
http://example.com?lang=en
처럼 파라미터 담아 요청! - lang파라미터 없어도 헤더에 자동 등록된 lang보고 국제화 사용 된다.
- 즉, 미국에서 접속 시 브라우저는 자국 언어인 en을 lang으로 헤더에 자동 등록되는 특징을 이용가능!
-
MessageSource 예시 - application.yml, messages.properties, messages_en.properties, TEST_CODE
application.yml 설정 -> 여기서 안하면 직접 클래스 만들어서 수동 스프링 빈 등록해야함(MessageSource메소드)
spring:
# 메시지 - thymeleaf 자동 연동
messages:
basename: messages
messages.properties, messages_en.properties 메시지 국제화!!
# messages.properties
hello=안녕
page.lobby=로비
page.gallery=전시실
page.studio=작품 제작실
label.item.location=작품위치
label.item.nickName=작가명
label.item.title=작품명
label.item.password=비밀번호
label.item.content=작품설명
label.item.product.date=제작일자
button.ok=확인
button.cancel=취소
button.next=다음
button.prev=다른 전시실 둘러보기
button.exit=전시실 나가기
button.product=갤러리에 전시하기
button.product.add=작품 전시하기
footer.tag=Copyright © 2023 YE-BEEN. All Rights Reserved
#
#
# messages_en.properties
hello=hello
page.lobby=lobby
page.gallery=gallery
page.studio=studio
label.item.location=location
label.item.nickName=nickName
label.item.title=title
label.item.password=password
label.item.content=content
label.item.product.date=date
button.ok=ok
button.cancel=cancel
button.next=next
button.prev=prev
button.exit=exit
button.product=product
button.product.add=add
footer.tag=Copyright © 2023 YE-BEEN. All Rights Reserved
TEST CODE
@SpringBootTest
public class MessageTest {
@Autowired
MessageSource ms;
@Test
void helloMessage() {
String result = ms.getMessage("hello", null, null);
System.out.println(result);
Assertions.assertEquals(result, "안녕");
}
}
국제화 예시 - Java Config로
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor()); //국제화 인터셉터 등록
}
//국제화 빈 -> 파라미터 lang 가져오는 용도
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
return interceptor;
}
//국제화 빈 -> 세션사용 및 Locale 자동 생성 용도
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.KOREA); // 또는 원하는 기본 로케일
return resolver;
}
//메시지소스 빈 -> 국제화 빈과 항상 세트로 사용하자.
//yml에서 이미 등록했으니 생략해도 될걸?
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames(
"message.message-common",
"org.egovframe.rte.fdl.idgnr.messages.idgnr",
"org.egovframe.rte.fdl.property.messages.properties"
);
messageSource.setCacheSeconds(60);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
댓글남기기