使用EJB服务调用进行验证,可以使用JSF验证器还是JSR303 bean验证? [英] Validation with an EJB service call, possible with JSF validator or JSR303 bean validation?

查看:199
本文介绍了使用EJB服务调用进行验证,可以使用JSF验证器还是JSR303 bean验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用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){}

我必须使用自定义验证器有没有注释?

解决方案


我必须使用自定义验证器有没有注释?


可以两种方式完成。



如果有自定义的JSF验证器,您只需要了解一个EJB不能注入到一个 @FacesValidator 。您基本上有3个选项:


  1. 从JNDI手动获取

  2. @ManagedBean 而不是 @FacesValidator

  3. 或安装OmniFaces,为 @EJB @Inject 中添加透明支持@FacesValidator

最终,你可以这样结束,假设你去 c code code code $ c
public class UsernameValidator implements Validator {

@EJB
private UserService service;

public void validate(FacesContext context,UIComponent component,Object submittedValue)throws ValidatorException {
if(submittedValue == null){
return; //让required =true句柄。
}

String username =(String)submittedValue;

if(service.exist(username){
throw new ValidatorException(new FacesMessage(Username already in use,choose another));
}
}

}

使用如下:

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

在JSR303 bean验证的情况下,您需要创建一个定制 @Constraint 注释使用自定义 ConstraintValidator 。您需要确保至少使用CDI 1.1,否则您无法在一个 ConstraintValidator ,您需要手动从 initialize()方法中从JNDI抓取它。你不能通过使它成为一个受管理的bean来解决它,甚至OmniFaces对此没有任何魔力。



例如

  @Constraint(validatedBy = UsernameValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD ,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface用户名{
String message()默认用户名已在使用中,选择另一个;
Class<?> [] groups()default {};
Class<?扩展有效载荷> [] payload()default {};
}

  public class UsernameValidator implements ConstraintValidator< Username,String> {

@EJB
私人UserService服务;

@Override
public void initialize(Username constraintAnnotation){
//如果没有在CDI 1.1上,那么您需要从JNDI手动抓取EJB。
}

覆盖
public boolean isValid(String username,ConstraintValidatorContext context){
return!service.exist(username);
}

}

和模型

  @Username 
private String username;


i want to validate my username using a select. if the username already is present in the database, validation fails.

i found some annotations for primefaces like this for example:

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

i didnt found a annotation solution for something like this:

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

Do i have to use a custom validator or are there annotations for it?

解决方案

Do i have to use a custom validator or are there annotations for it?

It can be done both ways.

In case of a custom JSF validator, you only need to understand that an EJB cannot be injected in a @FacesValidator. You've basically 3 options:

  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

Ultimately, you can end up like this, assuming that you went for the @ManagedBean approach:

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

}

Which is used as follows:

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

In case of JSR303 bean validation, you'd need to create a custom @Constraint annotation along with a custom ConstraintValidator. You need to make sure that you're using at least CDI 1.1, otherwise you can't inject an EJB in a ConstraintValidator and you'd need to resort to manually grabbing it from JNDI in initialize() method. You can't solve it by making it a managed bean and even OmniFaces hasn't any magic for this.

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

with

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

}

and in model

@Username
private String username;

这篇关于使用EJB服务调用进行验证,可以使用JSF验证器还是JSR303 bean验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆