使用EJB服务调用进行验证,可以使用JSF验证器或JSR303 bean验证吗?

时间:2013-11-22 13:25:17

标签: validation jsf-2 ejb bean-validation

我想使用select来验证我的用户名。如果用户名已经 存在于数据库中,验证失败。

我发现了一些像这样的素数的注释,例如:

@Size(min=2,max=5)  
private String name; 

我没有找到这样的注释解决方案:

try {
    dao.findUserByUserName(userName);

    message = new FacesMessage ("Invalid username!", "Username Validation Error");
    message.setDetail("Username already exists!");
    message.setSeverity(FacesMessage.SEVERITY_ERROR);

    throw new ValidatorException(message);
} catch (NoSuchUserException e) {}

我是否必须使用自定义验证器或是否有注释?

1 个答案:

答案 0 :(得分:5)

  

我是否必须使用自定义验证器或是否有注释?

可以两种方式完成。

如果是自定义JSF验证程序,您只需要了解EJB不能注入@FacesValidator。你基本上有3个选择:

  1. manually obtain it from JNDI
  2. or, make it a @ManagedBean instead of @FacesValidator
  3. or, install OmniFaces which adds transparent support for @EJB and @Inject in @FacesValidator
  4. 最终,假设你采用@ManagedBean方法,你可以这样结束:

    @ManagedBean
    @RequestScoped
    public class UsernameValidator implements Validator {
    
        @EJB
        private UserService service;
    
        public void validate(FacesContext context, UIComponent component, Object submittedValue) throws ValidatorException {
            if (submittedValue == null) {
                return; // Let required="true" handle.
            }
    
            String username = (String) submittedValue;
    
            if (service.exist(username) {
                throw new ValidatorException(new FacesMessage("Username already in use, choose another"));
            }
        }
    
    }
    

    使用如下:

    <h:inputText ... validator="#{usernameValidator}" />
    

    如果是JSR303 bean验证,则需要创建custom @Constraint annotationcustom ConstraintValidator。你需要确保你至少使用CDI 1.1,否则你不能在ConstraintValidator中注入EJB而你需要在initialize()方法中手动从JNDI中获取它。你无法通过将它变成托管bean来解决它,甚至OmniFaces也没有任何魔力。

    E.g。

    @Constraint(validatedBy = UsernameValidator.class)
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
    public @interface Username {
        String message() default "Username already in use, choose another";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    public class UsernameValidator implements ConstraintValidator<Username, String> {
    
        @EJB
        private UserService service;
    
        @Override
        public void initialize(Username constraintAnnotation) {
            // If not on CDI 1.1 yet, then you need to manually grab EJB from JNDI here.
        }
    
        Override
        public boolean isValid(String username, ConstraintValidatorContext context) {
            return !service.exist(username);
        }
    
    }
    

    和模型

    @Username
    private String username;