Spring @Autowired в пользовательский валидатор JSF

Spring @Autowired в пользовательский валидатор JSF

Вот сценарий: создание настраиваемого валидатора JSF, внедрение bean-компонента через@Autowired 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);
      }

    }

}

На странице JSF / XHTML свяжите его черезvalidatorId.

somepage.xhtml


    

проблема

Во время запуска приложения файл журнала показывает, что Spring создает bean-компонент «UsernameValidator», иUserService вводится успешно.

Однако при доступе со страницы JSF компонентuserService из «UsernameValidator» показывает значение null, что вызвало исключение NullPointerException.

Решение

Это потому, что@FacesValidator не управляется контейнером Spring. Чтобы исправить это, обратитесь к настраиваемому валидатору черезbinding вместоvalidatorId.

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