给定:JSF2 Form包含一些输入字段,包括密码字段。
主要目标:如果密码字段为空(导致password.isEmpty()==true
或password==null
),则应跳过验证和密码绑定!
No-Go:单独的DTO(我知道它会更干净,但我不允许这样决定)
view.xhtml:
<h:form id="someForm">
<h:outputLabel value="Password " />
<h:inputSecret id="password" value="#{myBackingBean.entity.password}" immediate="true" redisplay="false" required="false">
<f:validateBean disabled="true"/>
<f:validator validatorId="myPasswordValidator"/>
</h:inputSecret>
<p:message for="password" />
<p:commandButton value="Save" update="someForm">
<f:actionListener binding="#{myBackingBean.updateEntityAction()}" />
</p:commandButton>
</h:form>
MyPasswordValidator.java:
@FacesValidator(value = "myPasswordValidator")
public class MyPasswordValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
String password = (String) value;
if (password == null || password.isEmpty()) {
UIInput inputComponent = ((UIInput) component);
inputComponent.setValid(true);
inputComponent.setRequired(false);
}
return;
}
}
MyBackingBean.java:
@ManagedBean(name = "myBackingBean")
@ViewScoped
public class MyBackingBean extends GenericBackingBean<....> {
public ActionListener updateEntityAction(){
return new ActionListener() {
@Override
public void processAction(ActionEvent event)
throws AbortProcessingException {
// .... hybernate stuff
}
};
}
}
Entity.java:
class Entity{
@NotNull
private String password;
// ...
public void setPassword(String password) {
// do nothing if null
if(password == null || password.isEmpty()){
log.warn("Password not changed for some reason ....");
return;
}
// set and crypt password ...
}
这实际上有效,但仅适用于第一次提交,每次提交后第一次产生错误消息(没有例外......可能它会被某处吃掉......?)。有趣的是,消息中写着“kann nicht null sein'”(德语),我实际上并不知道是谁或者是什么产生了这个消息。
我的结论是,在第一次提交后,再次激活默认bean验证。
任何想法?
答案 0 :(得分:2)
此消息来自JSR303 bean验证注释@NotNull
。默认情况下,JSR303 bean验证在JPA EntityManager#persist()
和update()
期间执行 。
就像您可以通过<f:validateBean disabled="true">
在JSF中禁用JSR303 bean验证一样,您可以通过persistence.xml
中的以下条目禁用JPA中的JSR303 bean验证:
<validation-mode>none</validation-mode>
请注意,这会影响所有 JSR303 bean验证注释。您可能希望删除@NotNull
并使用条件required="true"
。
答案 1 :(得分:1)
消息“darf nicht null sein”来自ValidationMessages_de.properties
,您在JAR hibernate-validator-<version>.jar/org/hibernate/validator
中找到了一个消息。
所以你似乎是正确的,验证者反击的地方。通过JSF呈现此消息时,某些消息包保存
javax.faces.validator.BeanValidator.MESSAGE = {1} {0}
这样的消息就像:“密码”darf nicht null sein。在您的项目中,这已经改变了(在消息属性中查找键)或者可能从其他地方开始验证(Hibernate持久存在?)。
答案 2 :(得分:1)
找到了解决此问题的非黑客解决方案!
而不是写作:
<h:inputSecret id="password" value="#{myBackingBean.entity.password}" immediate="true" redisplay="false" required="false">
<f:validateBean disabled="true"/>
<f:validator validatorId="myPasswordValidator"/>
</h:inputSecret>
我不得不写:
<f:validateBean disabled="true">
<h:inputSecret id="password" value="#{myBackingBean.entity.password}" immediate="true" redisplay="false" required="false">
<f:validator validatorId="myPasswordValidator"/>
</h:inputSecret>
</f:validateBean>
第一个变体在请求后无法生存!
非常感谢您的提示和问候!