Chapter 20

WebConfigクラス

kazpgm
kazpgm
2021.12.20に更新

■WebConfigクラス

com.kaz01u.demo.WebConfig.java


・フォームクラスとメッセージの紐付けを行う。
 メッセージの、プロパティファイル名と文字コードを設定する。→1
 Validチェック用にメッセージプロパティファイルを設定する。→2

com.kaz01u.demo.WebConfig.java WebConfigクラス
package com.kaz01u.demo;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import com.kaz01u.demo.config.EnableSynchronizeOnSessionPostProcessor;

@Configuration
public class WebConfig {

    /**
     * メッセージのプロパティファイル名設定
     * メッセージの、プロパティファイル名と文字コードを設定する
     * @return ReloadableResourceBundleMessageSource
     */
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource bean = 
	                        new ReloadableResourceBundleMessageSource();
        //メッセージのプロパティファイル名(デフォルト)を指定します
        //下記ではmessages.propertiesファイルがセットされます
        bean.setBasename("classpath:messages"); //←1
        //メッセージプロパティの文字コードを指定します
        bean.setDefaultEncoding("UTF-8"); //←1
        return bean;
    }

    /**
     * Validチェック用メッセージプロパティファイル設定
     * Validチェック用メッセージプロパティファイルを設定する
     * @return LocalValidatorFactoryBean
     */
    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean() {
    LocalValidatorFactoryBean localValidatorFactoryBean = 
                                    new LocalValidatorFactoryBean();
    localValidatorFactoryBean.
                         setValidationMessageSource(messageSource()); //←2
    return localValidatorFactoryBean;

・同一セッション内のリクエストを同期化する
 これにより、@SessionAttributesアノテーション、またはsessionスコープのBeanを使用する場合は同一セッション内のリクエストを同期化する。
 具体的には、EnableSynchronizeOnSessionPostProcessor.java(同一セッションの同期化)を →4 WebConfig.java(@Configuration付きのクラス)に、@Bean付けて登録する。→3

com.kaz01u.demo.WebConfig.java WebConfigクラスの続き
    /**
     * @SessionAttributesアノテーション、またはsessionスコープのBeanを使用する場合は
     * 同一セッション内のリクエストを同期化する
     * @return EnableSynchronizeOnSessionPostProcessor
     */
    @Bean
    public EnableSynchronizeOnSessionPostProcessor enableSynchronizeOnSessionPostProcessor() {
    EnableSynchronizeOnSessionPostProcessor bean = 
                        new EnableSynchronizeOnSessionPostProcessor(); //←3
        return bean;
    }
}
com.kaz01u.demo.config.EnableSynchronizeOnSessionPostProcessor.java 同一セッションの同期化
package com.kaz01u.demo.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

/**
 * 同一セッションの同期化
 * 
 * ・@SessionAttributesアノテーション、またはsessionスコープのBeanを使用する場合は、
 *  同一セッション内のリクエストを同期化する必要がある。
 *  同期化しない場合、セッションに格納されているオブジェクトに、
 *  同時にアクセスする可能性があるため、想定外のエラーや、動作を引き起こす原因になりうる。
 * ・以下の様に、RequestMappingHandlerAdapterの、synchronizeOnSessionをtrueにして、
 *  同一セッション内のリクエストを同期化する。
 * ・当クラスをbean定義しておくと、同一セッションの同期化を行ってくれる。
 *  (bean定義は@Configuration付きのクラスで@bean付けて登録する。(例:WebConfigクラス)
 */
//log出力用
@Slf4j
public class EnableSynchronizeOnSessionPostProcessor 
                                         implements BeanPostProcessor { //←4
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
        throws BeansException {
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
        throws BeansException {
        if (bean instanceof RequestMappingHandlerAdapter) {
            RequestMappingHandlerAdapter adapter =
                (RequestMappingHandlerAdapter) bean;
            log.info("enable synchronizeOnSession => {}", adapter);
            //trueを指定すると、同一セッション内でのリクエストが同期化される。
            adapter.setSynchronizeOnSession(true);
        }
        return bean;
    }
}