かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Spring Bootを使って実行時にロケールを切り替える

実行時に相手に言語を選択させて表示言語を切り替えるっていうことがあると思います。 Spring Bootでもそういった機能があります。

まず、Appクラスで以下のBeanを公開します。

  • SessionLocaleResolver
  • LocaleChangeInterceptor

そしてWebMvcAutoCOnfigurationAdapterを継承してaddInterceptorsメソッドをオーバーライドしてLocaleChangeInterceptorを登録します。コードで書くと以下のような感じです。

package okazuki.validationEdu;

import java.util.Locale;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

@SpringBootApplication
public class App extends WebMvcAutoConfigurationAdapter {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Bean
    public SessionLocaleResolver localeResolver() {
        SessionLocaleResolver r = new SessionLocaleResolver();
        r.setDefaultLocale(Locale.JAPAN);
        return r;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor i = new LocaleChangeInterceptor();
        i.setParamName("lang");
        return i;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
}

あとは、message.properties, message_ja.properties, message_en.propertiesあたりを準備しておいて以下のようなThymeleafのテンプレート書けばOKです。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Insert title here</title>
</head>
<body>
    <a href="index?lang=ja" th:href="@{/index?lang=ja}">日本語</a>
    <br/>
    <a href="index?lang=en" th:href="@{/index?lang=en}">English</a>
    <hr />
    <span th:text="#{message}">こんにちは</span>
</body>
</html>

aタグの日本語とEnglishを押すと表示が切り替わります。

プログラム側でメッセージを取得するには以下のようになります。

package okazuki.validationEdu;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
    
    private static final Logger log = Logger.getLogger(HomeController.class);
    
    @Autowired
    MessageSource messageSource;
    
    @RequestMapping
    public String index() {
        log.info(this.messageSource.getMessage("message", null, LocaleContextHolder.getLocale()));
        return "index";
    }
}

MessageSourceをDIしてLocaleContextHolderからLocaleを取得してメッセージを取得します。