ここでは、カスタムJSFバリデーターを作成し、Springの `@ Autowired`を介してBeanを注入します。

UsernameValidator.java – カスタムJSFバリデータ

package com.mkyong.user;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.mkyong.user.bo.UserService;

@Component
@Scope("request")
@FacesValidator("UsernameValidator")
public class UsernameValidator implements Validator {

    @Autowired
    UserService userService;

    @Override
    public void validate(FacesContext context, UIComponent component,
        Object value) throws ValidatorException {

      String username = value.toString();

      if(userService.isUsernameDuplicated(username)){
        FacesMessage facesMsg = new FacesMessage("Username is duplicated");
        facesMsg.setSeverity(FacesMessage.SEVERITY__ERROR);
        throw new ValidatorException(facesMsg);
      }

    }

}

JSF/XHTMLページで、 `validatorId`を介してリンクしてください。

somepage.xhtml

<h:inputText id="username">
    <f:validator validatorId="usernameValidator"/>
</h:inputText>

問題

アプリケーションの起動時に、ログファイルはSpringが “UsernameValidator” Beanを作成し、 `UserService`が成功裏に注入されたことを示しています。

しかし、JSFページからのアクセス時に、「UsernameValidator」のBean「userService」がnullを表示しているため、NullPointerExceptionが発生しました。

解決策

これは、 `@ FacesValidator`がSpringのコンテナによって管理されていないためです。

それを修正するには、

validatorId`の代わりに

binding`を使ってカスタムバリデーターを参照してください。

__P.S Spring、CDI、JSFは本当に悪い仕事をしていました(お互いを統合しています)。将来のリリースで修正できることを願っています。

somepage.xhtml

<h:inputText id="username">
    <f:validator binding="#{usernameValidator}"/>
</h:inputText>

カスタムバリデータクラスでは、SpringまたはCDIのみを使用するため、 `@ FacesValidator`は必要ありません。

UsernameValidator.java – 春のみ

@Component
@Scope("request")
public class UsernameValidator implements Validator {

    @Autowired
    UserService userService;
   //...

UsernameValidator.java – CDIのみ

@Named
@RequestScoped
public class UsernameValidator implements Validator {

    @Autowired
    UserService userService;
   //...

もちろん、Springコンポーネントの自動スキャンが有効になっていることを確認してください。

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <context:component-scan base-package="com.mkyong"/>
    <context:annotation-config/>

</beans>

参考文献

オブジェクトが見つかりません]。 link://jsf2/custom-valid-in-jsf-2-0/[JSF 2カスタムバリデーター

例]