歩行訓練

おいっちにー!

Spring boot でValidationMessagesが文字化けするのをなんとかする。

Validationのエラーメッセージを国際化する方法を探していると、こういう記事があった

stackoverflow.com

ここで書いてあることは

  1. ValidationMessages.propertiesってのをresourcesのルートに置く
  2. @Digits(fraction = 0, integer = 3, message="{message.key}")って感じに書く

とのこと。実際やってみると、出来たことはできたのだが文字化けを起こした。

この文字化けどうやって直すのだろうと思って探すと

 

tono-n-chi.com

@Configurationなクラスに以下を貼っとけばOK。

と書いてあるが、そんなわけもなく、これでは動作しなかった。

他を探してみると

www.silverbaytech.com

という記事が見つかる。

ここでは

@Override
public Validator getValidator()
{
    return validator();
}

 って書いてあるので、これが足りない模様。でもどのクラスがこれを持っているのか。

WebMvcConfigurerAdapter (Spring Framework 4.2.1.RELEASE API)

の一番下にあった。

ということは、みんなやっているであろうPOSTメッセージのUTF-8化とかで持っているクラスに追記すればよいことになる。

他にも、「classpath:」と書いてあるので、resourcesのルートに置く意味もなくなる。同様にValidationPropertiesというファイル名にこだわる必要もなくなる。

実際にちゃんとそのパスが読めているのか不明なので、resouces配下にi18nというパッケージを作り「unko.properties」「unko_ja.properties」というファイルを用意して、jaの方に日本語のエラーメッセージを用意する。

procedure.hogehoge.check=unko / english

↑unko.properties

procedure.hogehoge.check=日本語おおお。japanese

↑unko_ja.properties

 

@Configuration
public class WebMvcConfig
extends WebMvcConfigurerAdapter
{

    @Bean
    public FilterRegistrationBean
    getFilterRegistrationBean()
    {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter( new CharacterEncodingFilter() );
        return filterRegistrationBean;
    }

    
    private static class CharacterEncodingFilter
    implements Filter
    {
        protected String encoding;

        public void init( FilterConfig filterConfig )
        throws ServletException
        {
            encoding = StandardCharsets.UTF_8.name();
        }
        
        public void doFilter( ServletRequest servletRequest
                            , ServletResponse servletResponse
                            , FilterChain filterChain )
        throws IOException, ServletException
        {
            HttpServletRequest request = ( HttpServletRequest )servletRequest;
            request.setCharacterEncoding( encoding );
            filterChain.doFilter( servletRequest, servletResponse );
        }
                
        
        public void destroy()
        {
            encoding = null;
        }
    }
    
    @Override
    public Validator getValidator()
    {
        return localValidatorFactoryBean();
    }

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean()
    {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource( messageSource() );
        return bean;
    }
 
    @Bean
    public MessageSource messageSource()
    {
        ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
        //bean.setBasename("classpath:/i18n/ValidationMessages");
        bean.setBasename("classpath:/i18n/unko");
       bean.setDefaultEncoding("UTF-8");
        return bean;
    }
}

これの下3つのクラスが今回の話で追加したメソッド

@Data
public class HogeFormData
{
    @Min( value=1, message="{procedure.hogehoge.check}" )
    int hogyaaa;

 こんな感じで呼び出すと日本語の表示に成功した。