JSFカスタムバリデーターに@ Springが追加されました.

Spring @JSFカスタムバリデーターに自動配線

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

UsernameValidator.java – Custom JSF validator

package com.example.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.example.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


    

問題

アプリケーションの起動時に、ログファイルにSpringが「UsernameValidator」Beanを作成し、UserServiceが正常に挿入されたことが示されます。

ただし、JSFページからアクセスすると、「UsernameValidator」のBeanuserServiceがnullを示しているため、NullPointerExceptionが発生しました。

溶液

これは、@FacesValidatorがSpringのコンテナによって管理されていないためです。 これを修正するには、validatorIdではなくbindingを介してカスタムバリデーターを参照します。

P.S Spring, CDI and JSF, did a really bad job here (integrate each others), hope they can fix it in future release.

somepage.xhtml


    

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

UsernameValidator.java – Spring Only

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

    @Autowired
    UserService userService;
    //...

UsernameValidator.java – CDI Only

@Named
@RequestScoped
public class UsernameValidator implements Validator {

    @Autowired
    UserService userService;
    //...

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

applicationContext.xml