title: jsf 2.2 + Spring 4 JSR-349 using Spring validator with JSF Locale
body: <p>I have an application using JSF 2.2 (with primefaces) in the front layer and Spring 4 on the business layer.</p>
  
  <p>I am using Tomcat 7.</p>
  
  <p>I am not using Spring MVC. Presentation Layer is pure JSF and I access Spring beans using @ManagedProperty(#{someSpringBean})</p>
  
  <p>I am using JSR-349 for client and server side validation. 
  I have my ValidationMessages.properties on the classpath.</p>
  
  <p>On client side validation there is no problem because Primefaces manages everything.</p>
  
  <p>On Facade layer (server side method validation) I need Spring to interpolate validation messages using JSF current locale (FacesContext.getCurrentInstance().getViewRoot().getLocale()).</p>
  
  <p>It's worth saying that the users of my application are allowed to change locale through menu option.</p>
  
  <p>So, how can I make Spring use JSF locale when interpolating messages in server side validation?</p>
  
  <p>I'll give you some code so you can understand better my needs:</p>
  
  <p>JSF Bean</p>
  
  <pre><code>@ManagedBean
  @ViewScoped
  public class RegisterBean {
  
      @ManagedProperty(value = "#{partnerServiceFacade}")
      private PartnerServiceFacade partnerServiceFacade;
  
      // properties...    
  
      public String registerPartner() {
          ...
          partner = partnerServiceFacade.registerPartner(partner);
      }    
  }
  </code></pre>
  
  <p>Facade interface:</p>
  
  <pre><code>@Validated    
  public interface PartnerServiceFacade {
  
      @PreAuthorize("hasRole('ROLE_USER')")
      public Partner registerPartner(@Valid Partner toRegister);
  
      //Other methods
  }
  </code></pre>
  
  <p>JPA Entity:</p>
  
  <pre><code>@Entity
  @Table(name = DBConstants.TABLE_PARTNER)
  @Inheritance(strategy = InheritanceType.JOINED)
  public class Partner extends XWeedDBEntity {
  
      private static final long serialVersionUID = 5692151244956513381L;
  
      @Id
      @Column(name = DBConstants.PARTNER_COL_PARTNER_NUMBER)
      private Integer partnerNumber;
  
      @NotEmpty
      @Column(name = DBConstants.PARTNER_COL_NAME, nullable = false)
      private String name;
  
      @NotEmpty
      @Column(name = DBConstants.PARTNER_COL_SURNAME, nullable = false)
      private String surname;
  
      @NotEmpty
      @Column(name = DBConstants.PARTNER_COL_LASTNAME)
      private String lastname;
  }
  </code></pre>
  
  <p>Spring configuration:</p>
  
  <pre><code>&lt;bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"&gt;
      &lt;property name="defaultEncoding" value="UTF-8"/&gt;
      &lt;property name="basename" value="ValidationMessages" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"&gt;
      &lt;property name="validationMessageSource" ref="messageSource" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Thanks in advance!</p>
  
  <hr>
  
  <p>I found the solution. Here it is:</p>
  
  <p>Spring validation configuration:</p>
  
  <pre><code>&lt;!-- SPRING MESSAGE LOCATOR --&gt;
  
  &lt;bean id="messageLocator" class="org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator"&gt;
      &lt;constructor-arg index="0" ref="messageSource" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- SPRING LOCALE MESSAGE INTERPOLATOR --&gt;
  
  &lt;bean id="messageInterpolator" class="org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator"&gt;
      &lt;constructor-arg index="0"&gt;
          &lt;bean id="hibernateMessageInterpolator" class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator"&gt;
              &lt;constructor-arg name="userResourceBundleLocator" ref="messageLocator" /&gt;
              &lt;constructor-arg name="cacheMessages" value="true"/&gt;
          &lt;/bean&gt;
      &lt;/constructor-arg&gt;
  &lt;/bean&gt;
  
  &lt;!-- SPRING VALIDATOR --&gt;
  
  &lt;bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"&gt;
      &lt;property name="messageInterpolator" ref="messageInterpolator" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- SPRING ANNOTATION VALIDATION CONFIGURATION --&gt;
  
  &lt;bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"&gt;
      &lt;property name="validator" ref="validator"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Phase Listener to manage Locale:</p>
  
  <pre><code>public class LocalePhaseListener implements PhaseListener {
  
  // Constants --------------------------------------------------------------------------------------------------------------
  
  private static final long serialVersionUID = 3678092859009088388L;
  
  // Overridden methods -----------------------------------------------------------------------------------------------------
  
  @Override
  public void afterPhase(PhaseEvent event) {
  }
  
  @Override
  public void beforePhase(PhaseEvent event) {
      HttpSession session = (HttpSession) event.getFacesContext().getExternalContext().getSession(false);
      Locale locale = ((UserBean) session.getAttribute("userBean")).getLocale();
      LocaleContextHolder.resetLocaleContext();
      LocaleContextHolder.setLocale(locale);
  }
  
  @Override
  public PhaseId getPhaseId() {
      return PhaseId.INVOKE_APPLICATION;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Using LocaleContextMessageInterpolator you enforce Spring to use the locale in LocaleContextHolder, and in the PhaseListener you fill LocaleContextHolder locale with JSF locale.</p>