Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate validator change locale at runtime

I made an application with hibernate and use annotations to do the validation. I realized that to translate the message into my language I have to put in the resources folder a file called ValidationMessage_xx.properties. The problem is that what should be the default language but I have to give visitors the option to change the language of the website and thus also that of the validation

Add code of class where i use validator

class example {

    @NotEmpty
    private String fieldOne;
    @NotEmpty
    private String fieldTwo;

    public String getFieldOne(){
        return fieldOne;
    }

    public void setFieldOne(String fieldOne){
        this.fieldOne = fieldOne
    }

    ....
}
like image 915
ciro Avatar asked Aug 05 '16 15:08

ciro


1 Answers

The default locale ( e.g. ValidationMessage.properties ) can be any language you want it to be, this is entirely application specific. Because I speak English, I tend to prefer making that file contain English based translations and I extend to other languages as needed.

As for selecting the appropriate locale choice, you will need to provide a way of passing that value downstream from your application tier to the validation framework.

For example, your application could setup a thread local variable or use LocalContextHolder if you're using spring, that will allow you to set a thread specific Locale that you can access statically downstream in code.

In my past experience, we typically have a single resource bundle that we want to use in bean validation that is shared with the controllers and services. We provide bean validation a resolver implementation that loads that resource bundle based on the thread local variable and exposes internationalization messages this way.

A provided example:

// This class uses spring's LocaleContextHolder class to access the requested
// application Locale instead a ThreadLocal variable.  See spring's javadocs
// for details on how to use LocaleContextHolder.
public class ContextualMessageInterpolator 
   extends ResourceBundleMessageInterpolator {
  private static final String BUNDLE_NAME = "applicationMessages";

  @Override
  public ContextualMessageInterpolator() {
    super( new PlatformResourceBundleLocator( BUNDLE_NAME ) );
  }

  @Override
  public String interpolate(String template, Context context) {
    return super.interpolate( template, context, LocaleContextHolder.getLocale() );
  }

  @Override
  public String interpolate(String template, Context context, Locale locale) {
    return super.interpolate( template, context, LocaleContextHolder.getLocale() );
  }
}

The next step is you need to provide the ContextualMessageInterpolator instance to Hibernate Validator. This can be done by createing a validation.xml and placing in META-INF under the root of the classpath. In a web application, this would be WEB-INF/classes/META-INF.

<validation-config
    xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration"
    version="1.1">
  <message-interpolator>com.company.ContextualMessageInterpolator</message-interpolator>
</validation-config>

Since I used applicationMessages as my bundle name, just create a default applicationMessages.properties file and subsequent locale-specific versions and add your validation message strings to those property files.

javax.validation.constraints.NotNull.message=Field must not be empty.
javax.validation.constraints.Max.message=Field must be less-than or equal-to {value}.
javax.validation.constraints.Min.message=Field must be greater-than or equal-to {value}.

Hope that helps.

like image 180
Naros Avatar answered Sep 17 '22 23:09

Naros