メッセージ、国際化

# メッセージ機能
- message.propertiesというメッセージ管理用ファイルを作成し、様々なメッセージを1か所で管理する。
    そして、HTMLに該当データをキー値で呼んで使用させる。

- ファイルは/resources/message/propertiesに置けばよい。
    ```
    messages.properties
    
    hello=こんにちは
    hello.name=こんにちは {0}  // パラメーターを設定する
    ```
# 国際化機能
- message.propertiesを各国別に別途管理できる。
- message_en.propertiesなどでファイル名を変えて作れば良い。
    ```
    messages_en.properties
    
    hello=hello
    hello.name=hello {0}
    ```
- 他のファイル名のメッセージファイルを登録したい場合は、application.propertiesにファイル名を登録しなければならない。
    - SpringBootでは、基本設定で以下の内容を自動登録してくれる。
    ```
    spring.messages.basename=messages
    ```

# Springが提供するメッセージと国際化機能

1. メッセージ機能
- SpringBootではMessageSourceが自動登録され、@Autowiredだけ付ければよい。
    ```java   
    @SpringBootTest
    public class MessageSourceTest {
    
        @Autowired
        MessageSource ms;
    
        @Test
        void helloMessage() {
    				// getMessageのパラメーターは
    				// code, args, defaultMessage, localeがある。
    				String reuslt = ms.getMessage("hello, null, Locale.KOREA);
    				assertThat(result).isEqualTo("こんにちは");
        }
    
        @Test
        void argumentMessage() {
            String message = ms.getMessage("hello.name", new Object[]{"Spring"}, null);
            assertThat(message).isEqualTo("こんにちは Spring");
        }
    }
    ```

# ウェブアプリケーションにメッセージ&国際化を適用する
1. メッセージの適用
    - タイムリーフを使うと#{···}表現式を通じてスプリングのメッセージを便利に照会することができる。
    ```html
    <div th:text="#{hello}"></div>

    <div th:text="#{hello.name(${item.itemName})}"></div>
    ```
2. 国際化の適用
    - 言語設定と関連してはLocale Resolverを使用するが、具現体としては以下のようなものがある。
    
    | Locale Resolver 種類 | set Locale() | 説明 |
    | --- | --- | --- |
    | AcceptHeaderLocaleResolver　（SpringBoot Default） | サポート× |　ウェブブラウザが送信したヘッダーのAccept-Language値に基づいてLocaleを選択する。|
    | CookieLocaleResolver | サポート○ CookieにLocale情報保存 | SessionからLocale情報を求める。|
    | SessionLocaleResolver | サポート○ SessionにLocale情報保存 | CookieからLocale情報を求める。|
    | FixedLocaleResolver | サポート× | ウェブリクエストにかかわらず特定のLocaleに設定する。|

    1. AcceptHeaderLocaleResolver
        - SpringBootでDefaultに設定している。
        - Chromeブラウザの場合、設定>言語を検索して優先順位を変更すれば、Accept-Languageを変更することができる。
        ![スクリーンショット 2024-01-03 17.17.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/b986402a-ea0e-1216-8c9e-d97f72e1882b.png)
        ![스크린샷 2024-01-01 18.11.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/ed066b71-1bf3-8916-a55b-806ca2bef5c1.png)

    2. CookieLocaleResolver 
        - 直接言語を選択してその値をCookieに入れておきたい時に使用する。
        - Cookieを利用すれば、Locale情報が維持され、ユーザーがサイトを離れて戻ってきても以前に選択した言語設定を維持することができ、さらにお勧めする。
        ```java
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.LocaleResolver;
        import org.springframework.web.servlet.i18n.CookieLocaleResolver;
        
        import java.util.Locale;
        
        @Configuration
        public class HomeConfig {
        
            @Bean
            public LocaleResolver localeResolver() {
                CookieLocaleResolver localeResolver = new CookieLocaleResolver();
                localeResolver.setCookieName("lang");
                localeResolver.setDefaultLocale(new Locale("ja"));
                localeResolver.setCookieHttpOnly(true);
                return localeResolver;
            }
        
        }
        ```
        ```html
        <a href="/changeLanguage?language=ko" th:text="#{korean}"></a>
        <a href="/changeLanguage?language=ja" th:text="#{japanese}"></a>
        <a href="/changeLanguage?language=en" th:text="#{english}"></a>
        ```
        ```java
        private final LocaleResolver localeResolver;

        @Autowired
        public HomeController(LocaleResolver localeResolver){
            this.localeResolver = localeResolver;
        }
        
        @GetMapping("/changeLanguage")
        public String changeLanguage(String language, HttpServletRequest request, HttpServletResponse response) {
        		localeResolver.setLocale(request, response, new Locale(language));
        		return "redirect:"+request.getHeader("Referer");
        }
        ```

    3. SessionLocaleResolver 
        - 直接言語を選択してその値をCookieに入れておきたい時に使用する。
        ```java
        @Bean
        public LocaleResolver localeResolver() {
            SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
            sessionLocaleResolver.setDefaultLocale(new Locale("ko"));
            return sessionLocaleResolver;
        }
        ```
        ```html
        <a href="/changeLanguage?language=ko" th:text="#{korean}"></a>
        <a href="/changeLanguage?language=ja" th:text="#{japanese}"></a>
        <a href="/changeLanguage?language=en" th:text="#{english}"></a>
        ```
        ```java
        private final LocaleResolver localeResolver;

        @Autowired
        public HomeController(LocaleResolver localeResolver){
            this.localeResolver = localeResolver;
        }
        
        @GetMapping("/changeLanguage")
        public String changeLanguage(String language, HttpServletRequest request, HttpServletResponse response) {
        		localeResolver.setLocale(request, response, new Locale(language));
        		return "redirect:"+request.getHeader("Referer");
        }
        ```