JavaJSF关于自定义验证

JavaJSF关于自定义验证,java,web-applications,jsf-2,Java,Web Applications,Jsf 2,我在自定义验证中使用这种方式如果我假设我有以下表格,我会有点困惑这种方式是否正确: <h:form id="myForm> <h:outputText value="user name" /> <h:inputText value="#userBean.userName" id="userName" /> <h:outputText value="Password" /> <h:inputText value="#userBean.

我在自定义验证中使用这种方式如果我假设我有以下表格,我会有点困惑这种方式是否正确:

<h:form id="myForm>
 <h:outputText value="user name" />
 <h:inputText value="#userBean.userName" id="userName" />

 <h:outputText value="Password" />
 <h:inputText value="#userBean.Password" id="passwd" />
</h:form>
以及用于验证托管Bean字段和实现的自定义验证器,如:

@Override
public validate(FacesContext context, UIComponent component, Object value) throws ValidatorException{
Map<String, String> params = context.getExternalContext().getRequestParametersMap();

String username = params.get("myForm:username");
String pass = params.get("myForm:passwd");

// validate : if fields are not null check if the user exists if the result is empty , throws a validation Message Error
}
@覆盖
公共验证(FacesContext上下文、UIComponent组件、对象值)引发ValidatorException{
Map params=context.getExternalContext().getRequestParametersMap();
字符串username=params.get(“myForm:username”);
字符串pass=params.get(“myForm:passwd”);
//验证:如果字段不为null,则检查用户是否存在如果结果为空,则抛出验证消息错误
}

我的问题是:像这样检索托管bean值是真是假???

注意
validate
方法的坚定性。它有一个
UIComponent
参数,该参数是通过该方法验证的组件。此
UIComponent
具有当前值(
getValue()
)和用户提交的值(
getSubmittedValue()

您可能必须将该
UIComponent
强制转换为正在验证的特定类型的组件(在本例中,它是
UIInput

现在,如果您要在登录之前验证用户名和密码,有几种方法。在您的情况下,使用密码字段作为添加的参数验证用户名字段就足够了。您可以通过以下方式实现这一点:

<h:outputText value="user name" />
<h:inputText value="#userBean.userName" id="userName" validator="#{yourBean.validateLogin}">
    <f:attribute name="pass" value="#{passwordField}" />
</h:inputText>

<h:outputText value="Password" />
<h:inputText value="#userBean.Password" id="passwd" binding="#{passwordField}"/>

由于所有这些都是在验证阶段完成的,因此值尚未在托管bean中设置,这就是为什么您必须对提交的值进行一些处理。

您基本上是在错误的方向上寻找解决方案。验证仅适用于单个提交的值,例如最小/最大长度、非空/空、正则表达式模式等。但您希望基于所有提交的值调用业务操作:登录用户。这并不完全是输入验证

只需将
required=“true”
添加到两个输入组件中,并在action方法中执行作业

例如


我的问题的目的是,在Validator Calss中发现更多关于validate()方法的信息,并发现定制验证的完美解决方案。。。。。。登录表单就是我问题的一个例子,“完美”的解决方案是相对的。我给出的一个,tough,包含了跨组件验证的主题,而不是单个组件的验证。您的示例是一个很好的例子,因为它包含多个字段,但是这个解决方案并不局限于一个主题(在本例中是登录)。它管理任何类型的验证。我还以bean方法为例。您可以使用自定义验证器,注册它,并在类的已实现的
validate
方法上使用与该方法完全相同的逻辑。ok。。。。如果客户机填写了所需的输入,而我喜欢点击数据库(例如),该怎么办?
<h:outputText value="user name" />
<h:inputText value="#userBean.userName" id="userName" validator="#{yourBean.validateLogin}">
    <f:attribute name="pass" value="#{passwordField}" />
</h:inputText>

<h:outputText value="Password" />
<h:inputText value="#userBean.Password" id="passwd" binding="#{passwordField}"/>
public void validateLogin(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    //I suppose it's a typo, but your validate method lacks the return type.
    String username = (String) value;
    UIInput passwordInput = component.getAttributes().containsKey("pass") ? 
        (UIInput) component.getAttributes().get("pass") : null;
    if(passwordInput != null) {
        //Just to be sure the input was added as a parameter successfuly
        String submittedPassword = passwordInput.getSubmittedValue();
        //Now, do your validations based on the strings "username"
        //and "password".
    }
}
@ManagedBean
@RequestScoped
public class UserBean {

    private String userName;
    private String password;

    @EJB
    private UserService service;

    public String login() {
        User user = service.find(userName, password);

        if (user != null) {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap("user", user);
            return "home?faces-redirect=true";
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login"));
            return null;
        }
    }

    // ...
}