我正在使用WAS 8.0.0.5的MyFaces 2.0.4和CDI(不能在不丢失CDI的情况下取代WAS 8版本的JSF 2.0)。
我有2个自定义验证器注册到组件。第一个进行多场比较。第二个验证器使用CDI注入SSB,它使用实体管理器来调用数据库。
如果输入导致第一个验证器故意失败的信息,则仍会执行第二个验证器。为什么?如果第一次验证失败,我该如何避免第二次验证?我认为如果一个验证器失败,那么所有后续验证都会被绕过。
<h:form id="registrationForm">
<fieldset>
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
<legend>Register</legend>
<div class="form-row">
<h:outputLabel for="userId" value="*User Id"/>
<h:inputText id="userId" value="#{registration.userId}" required="true" size="20">
<f:validator validatorId="userIdPasswordValidator" />
<f:attribute name="passwordComponent" value="#{passwordComponent}"/>
<f:validator binding="#{duplicateUserValidator}" /> <-- uses CDI
</h:inputText>
</div>
<div class="form-row">
<h:outputLabel for="password" value="*Password"/>
<h:inputSecret id="password" type="password" binding="#{passwordComponent}" value="#{registration.password}" required="true">
</h:inputSecret>
</div>
<div class="form-row">
<h:outputLabel for="confirmPassword" value="*Confirm Password"/>
<h:inputSecret id="confirmPassword" type="password" value="#{registration.confirmPassword}" required="true" />
</div>
<div class="form-row">
<h:commandButton styleClass="btn btn-warning" value="Register" type="submit" action="#{registration.register}" />
</div>
</fieldset>
</h:form>
第一个验证员:
@FacesValidator("userIdPasswordValidator")
public class UserIdPasswordValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String userId = (String)value;
UIInput passwordInput = (UIInput)component.getAttributes().get("passwordComponent");
String password = (String) passwordInput.getSubmittedValue();
if (userId.equals(password)) {
FacesMessage message = new FacesMessage(null, "The Password cannot be the same as your User ID.");
throw new ValidatorException(message);
}
}
}
第二个验证员:
@Named
@RequestScoped
public class DuplicateUserValidator implements Validator {
@Inject
UserService userService;
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (userService.getUser(value.toString()) != null) {
FacesMessage message = new FacesMessage(null, "This User ID is already registered. Please logon or choose another one to register.");
throw new ValidatorException(message);
}
}
}
答案 0 :(得分:3)
要达到预期的结果,您应该按照以下oracle摘录中的说明调用renderResponse()
:
如果任何验证方法或事件侦听器在当前FacesContext上调用renderResponse,则JavaServer Faces实现将跳转到渲染响应阶段。
但这就是验证阶段工作的方式我害怕。 From oracle:
在此阶段,JavaServer Faces实现处理在树中的组件上注册的所有验证程序。它检查指定验证规则的组件属性,并将这些规则与为组件存储的本地值进行比较。
如果本地值无效,JavaServer Faces实现会向FacesContext实例添加错误消息
此处的关键短语是处理所有验证程序,向FacesContext实例添加错误消息。虽然这里不是很清楚,但它意味着整个验证阶段将完成并且消息排队。完成后,它将进入适当的阶段。