Spring @Autowired dans le validateur personnalisé JSF

Spring @Autowired dans le validateur personnalisé JSF

Voici le scénario, créez un validateur JSF personnalisé, injectez un bean via les@Autowired de Spring.

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);
      }

    }

}

Dans la page JSF / XHTML, liez-le viavalidatorId.

somepage.xhtml


    

Problème

Lors du démarrage de l'application, le fichier journal indique que Spring est créé le bean «UsernameValidator» et queUserService est injecté avec succès.

Cependant, lors de l'accès à partir de la page JSF, le beanuserService de «UsernameValidator» affiche null, provoquant une NullPointerException.

Solution

En effet,@FacesValidator n’est pas géré par le conteneur de Spring. Pour résoudre ce problème, référencez le validateur personnalisé viabinding, au lieu devalidatorId.

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


    

Dans la classe de validation personnalisée, utilise uniquement Spring ou CDI,@FacesValidator n'est pas nécessaire.

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;
    //...

Bien sûr, assurez-vous que l'analyse automatique des composants Spring est activée.

applicationContext.xml