Spring @Autowired in den benutzerdefinierten JSF-Validator

Spring @Autowired in den benutzerdefinierten JSF-Validator

In diesem Szenario erstellen Sie einen benutzerdefinierten JSF-Validator und injizieren eine Bean über Spring's@Autowired.

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

    }

}

Verknüpfen Sie die JSF / XHTML-Seite übervalidatorId.

somepage.xhtml


    

Problem

Während des Anwendungsstarts zeigt die Protokolldatei, dass Spring die Bean "UsernameValidator" erstellt hat undUserService erfolgreich injiziert wurde.

Beim Zugriff von der JSF-Seite zeigt die BeanuserService von "UsernameValidator" jedoch null an, was eine NullPointerException verursacht.

Lösung

Dies liegt daran, dass@FacesValidator nicht vom Spring-Container verwaltet wird. Um dies zu beheben, verweisen Sie auf den benutzerdefinierten Validator überbinding anstelle vonvalidatorId.

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


    

In der benutzerdefinierten Validator-Klasse wird nur Spring oder CDI verwendet.@FacesValidator ist nicht erforderlich.

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

Vergewissern Sie sich natürlich, dass die automatische Prüfung von Spring-Komponenten aktiviert ist.

applicationContext.xml