애플리케이션 국제화
src/main/resource에서 messages.properties 찾았을 때 자동으로 MessageSource를 구성한다
spring.messages.basename= 쉼표로 구분된 기본 이름 목록, 기본값 messages
spring.messages.encoding= 메시지 묶음 인코딩 방식, 기본값 UTF-8
spring.messages.always-use-message-format= MessageFormat이 전체 메시지에 적용되는지 여부, 기본값 false
spring.messages.fallback-to-system-locale= 감지된 언어의 리소스 묶음이 없는 경우 사용되는 시스템 언어, 비활성화되면 기본 파일로부터 기본값을 불러온다. 기본값 false
spring.messages.use-code-as-default-message= 메시지를 찾지 못했을 때 NoSuchMessageException 예외 처리대신 기본 메시지로 메시지 코드를 사용한다. 기본값 false
spring.messages.cache-duration= 캐시 주기, 기본값 forever
#클라우드나 다른 외부 호스트에 애플리케이션 배포시 fallback-to-system-local false로 설정하는것이 좋다
1. 메시지 활용하기
타임리프에서는 #{변수명} 이용하면된다.
resources 밑에 messages.properties 추가해서 작성
# messages.properties
main.title=Spring Boot Recipes - Library
index.title=Library
index.books.link=List of books
books.list.title=Available Books
books.list.table.title=Title
books.list.table.author=Author
books.list.table.isbn=ISBN
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>제목</title>
</head>
<body>
<h1 th:text="#{index.title}">messagee..</h1>
<a th:href="@{/books.html}" href="#" th:text="#{index.books.link}">List of books</a>
</body>
</html>
list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table>
<thead>
<tr>
<th>제목</th>
<th>작가</th>
<th>ISBN</th>
</tr>
</thead>
<tbody>
<tr th:each="book : ${books}">
<td th:text="${book.title}">제목</td>
<td th:text="${book.authors}">작가</td>
<td>
<a th:href="@{/book.html(isbn=${book.isbn})}" href="#" th:text="${book.isbn}">1234567890123</a>
</td>
</tr>
</tbody>
</table>
<p th:text="#{books.list.title}"></p>
<p th:text="#{books.list.table.title}"></p>
<p th:text="#{books.list.table.author}"></p>
<p th:text="#{books.list.table.isbn}"></p>
</body>
</html>
JSP 아래 방식으로 하면된다. 출처 : http://jmlim.github.io/spring/2018/11/28/spring-boot-Internationalization/
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <-- 이와같이 태그 선언 후
<spring:message code="alert.loginEmail" /> 원하는 텍스트가 쓰여진 메세지 코드값 정의
다국어처리
스프링 MVC에는 LocaleResolver 인터페이스의 기본 구현체가 몇 가지 있다.
사용자가 사용하려는 언어를 덮어쓸 수 있도록 LocaleChangeInterceptor라는 HandleInterceptor를 제공한다
1) HTTP 요청 헤더로 언어 결정
스프링부트에서 기본으로 등록된 언어 리졸버는 AcceptHeaderLocaleResolver 이다.
HTTP요청의 Accept-Language 헤더를 감지해 언어를 결정한다.
package com.example.demo.library;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.util.Locale;
@Configuration
@EnableWebMvc
public class ApplicationContextConfig {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
// 언어&국가정보가 없는 경우 한국으로 인식하도록 설정
localeResolver.setDefaultLocale(Locale.KOREA); // ko_KR
Locale.setDefault(Locale.KOREA);
return localeResolver;
}
}
2) 세션 속성으로 언어 결정하기
언어를 결정하는 옵션에는 SessionLocaleResolver도 있다.
사용자 세션에 사전 정의된 속성을 감지해 언어를 결정한다.
세션 속성이 없는 경우에는 언어 리졸버는 Accopt-Language HTTP 헤더로부터 기본언어를 결정
package com.example.demo.library;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@Configuration
@EnableWebMvc
public class InternationalConfig implements WebMvcConfigurer {
@Bean // 1 LocaleResolver
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
// slr.setDefaultLocale(Locale.JAPAN);
// setDefaultLocal을 지정하지 않을 경우 서버 정보?의 국가가 자동으로 설정됨 (Locale.KOREA)
return slr;
}
}
3) 쿠키로 언어 결정하기
사용자 브라우저의 쿠키를 감지해 언어를 결정하는 CookieLocalResolver를 사용할 수 있다.
package com.example.demo.library;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import java.util.Locale;
@Configuration
@EnableWebMvc
public class ApplicationContextConfig {
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setCookieName("language");
cookieLocaleResolver.setCookieMaxAge(3600);
cookieLocaleResolver.setDefaultLocale(new Locale("en"));
return cookieLocaleResolver;
}
}
4) 고정된 언어 사용
package com.example.demo.library;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
import java.util.Locale;
@Configuration
@EnableWebMvc
public class ApplicationContextConfig {
@Bean
public LocaleResolver localeResolver() {
FixedLocaleResolver fixedLocaleResolver = new FixedLocaleResolver();
fixedLocaleResolver.setDefaultLocale(new Locale("en"));
return fixedLocaleResolver;
}
}
5) 사용자 언어 변경하기
LocaleResolver 는 쿠키로도 가능하지만 저는 그냥 세션으로 시작
package com.example.demo.library;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@Configuration
@EnableWebMvc
public class InternationalConfig implements WebMvcConfigurer {
@Bean // 1 LocaleResolver
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
// slr.setDefaultLocale(Locale.JAPAN);
// setDefaultLocal을 지정하지 않을 경우 서버 정보?의 국가가 자동으로 설정됨 (Locale.KOREA)
return slr;
}
@Bean // 2 LocaleChangeInterceptor
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override // 3 addInterceptors: WebMvcConfigurer에 있는 것을 구현한 것
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
package com.example.demo.library;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
public class InternationalController {
@RequestMapping("/international")
public String getInternationalPage() {
return "international";
}
@ResponseBody
@RequestMapping("/sessionClear")
public String sessionClear(HttpSession ss) {
ss.invalidate();
return "OK";
}
}
international.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title data-th-text="#{title}"></title>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
</head>
<body>
<h1 data-th-text="#{welcome}"></h1>
<span data-th-text="#{lang.change}"></span>:
<select id="locales" >
<option value="ko" data-th-text="#{lang.ko}"
data-th-selected=" ${param.lang eq null or param.lang.toString()=='ko' }" />
<option value="en" data-th-text="#{lang.en}"
data-th-selected=" ${param.lang?.toString()=='en' }" />
<option value="ja" data-th-text="#{lang.ja}"
data-th-selected=" ${param.lang?.toString()=='ja' }" />
</select>
<button type=button id=btnClear >TEST</button>
<script>
$('#locales').change(() => {
var selectedOption = $('#locales').val();
if (selectedOption != ''){
window.location.replace('international?lang=' + selectedOption);
}
})
$('#btnClear').click( ()=> {
$.get("sessionClear", res => {
alert(res)
})
})
</script>
</body>
</html>
messages_ko.properties
title=국제화
welcome=안녕하세요. 홈페이지에 오신 것을 환영합니다.
lang.change=언어 변경
lang.en=영어
lang.ja=일본어
lang.ko=한국어
messages_ja.properties
title=国際化
welcome=こんにちは。私のホームにようこそ
lang.change=言語を変更する
lang.en=英語
lang.ja=日本語
lang.ko=韓国語
messages_en.properties
main.title=title=Internationalization
title=Internationalization
welcome=Hello! Welcome to our website!
lang.change=Change the language
lang.en=English
lang.ja=Japanese
lang.ko=Korean
기본 접속시)
?lang=en 붙일시)
?lang=ja 붙일시)
브라우저에서 언어변경방법)
크롬과 비슷한 웨일브라우저로 테스트
한국어가 1순위로 잡혀있는것을 일본어로 임시로 올려본다.
?lang=ja 접속안하고 기본접속시 자동으로 일본어로 잡히는것을 알수있다
참고사이트)
https://www.baeldung.com/spring-boot-internationalization
https://engkimbs.tistory.com/717
https://mytory.net/2019/04/14/spring-boot-internationalization.html
http://yoonbumtae.com/?p=754 ★★★★★★
http://progtrend.blogspot.com/2018/07/spring-boot-internationalization.html
https://lahuman.jabsiri.co.kr/87
https://galid1.tistory.com/528
the value of request.getLocale() is determined by your web container such as Tomcat, so spring localeResolver can't not affect this value. this value is Locale.getDefault(), if you want to change your default locale, you can add one more code
-> message.properties 파일을 다른곳으로 classpath 할때 ReloadableResourceBundleMessageSource
'WEB > 스프링 부트 2' 카테고리의 다른 글
Jetty SSL, Http to Https (0) | 2020.02.06 |
---|---|
Spring SSL, Http to Https (0) | 2020.02.05 |
타임리프(thymeleaf) (0) | 2020.02.04 |
스프링 MVC (0) | 2020.02.04 |
책1 (0) | 2020.02.03 |