読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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を取得してメッセージを取得します。