在我的JSF / Facelets应用程序中,这是我表单部分的简化版本:
<h:form id="myform">
<h:inputSecret value="#{createNewPassword.newPassword1}" id="newPassword1" />
<h:message class="error" for="newPassword1" />
<h:inputSecret value="#{createNewPassword.newPassword2}" id="newPassword2" />
<h:message class="error" for="newPassword2" />
<h:commandButton value="Continue" action="#{createNewPassword.continueButton}" />
</h:form>
我希望能够根据continueButton()方法中发生的事情为特定的h:message标记分配错误。需要为newPassword和newPassword2显示不同的错误。验证器不会真正起作用,因为将传递结果的方法(来自DB)在continueButton()方法中运行,并且运行两次太昂贵。
我无法使用h:messages标记,因为该页面有多个地方需要显示不同的错误消息。当我尝试这个时,页面显示每条消息的重复。
我试过这个是最好的猜测,但没有运气:
public Navigation continueButton() {
...
expensiveMethod();
if(...) {
FacesContext.getCurrentInstance().addMessage("newPassword", new FacesMessage("Error: Your password is NOT strong enough."));
}
}
我错过了什么?任何帮助将不胜感激!
答案 0 :(得分:57)
FacesContext.addMessage(String, FacesMessage)需要组件的 clientId ,不它的 id 。如果您想知道为什么,请考虑将控件作为dataTable的子项,使用相同的控件标记每行的不同值 - 可以为每行打印不同的消息。 id 始终相同; clientId 每行唯一。
所以“myform:mybutton”是正确的值,但硬编码这是不明智的。查找将在视图和业务逻辑之间创建较少的耦合,并且是一种在更具限制性的环境(如portlet)中工作的方法。
<f:view>
<h:form>
<h:commandButton id="mybutton" value="click"
binding="#{showMessageAction.mybutton}"
action="#{showMessageAction.validatePassword}" />
<h:message for="mybutton" />
</h:form>
</f:view>
托管bean逻辑:
/** Must be request scope for binding */
public class ShowMessageAction {
private UIComponent mybutton;
private boolean isOK = false;
public String validatePassword() {
if (isOK) {
return "ok";
}
else {
// invalid
FacesMessage message = new FacesMessage("Invalid password length");
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(mybutton.getClientId(context), message);
}
return null;
}
public void setMybutton(UIComponent mybutton) {
this.mybutton = mybutton;
}
public UIComponent getMybutton() {
return mybutton;
}
}
答案 1 :(得分:24)
如果有人好奇,我能够根据你的所有回答结合出来找出来!
这是在Facelet中:
<h:form id="myform">
<h:inputSecret value="#{createNewPassword.newPassword1}" id="newPassword1" />
<h:message class="error" for="newPassword1" id="newPassword1Error" />
<h:inputSecret value="#{createNewPassword.newPassword2}" id="newPassword2" />
<h:message class="error" for="newPassword2" id="newPassword2Error" />
<h:commandButton value="Continue" action="#{createNewPassword.continueButton}" />
</h:form>
这是在continueButton()方法中:
FacesContext.getCurrentInstance().addMessage("myForm:newPassword1", new FacesMessage(PASSWORDS_DONT_MATCH, PASSWORDS_DONT_MATCH));
它有效!谢谢你的帮助!
答案 2 :(得分:6)
您还必须在对addMessage()的调用中包含FormID。
FacesContext.getCurrentInstance().addMessage("myform:newPassword1", new FacesMessage("Error: Your password is NOT strong enough."));
这应该可以解决问题。
问候。
答案 3 :(得分:4)
请记住:
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage( null, new FacesMessage( "The message to display in client" ));
也有效,因为当 null 指定为第一个参数时,它将应用于整个表单。
更多信息:coreservlets.com //过时
答案 4 :(得分:2)
JSF是一头野兽。我可能会遗漏一些东西,但我曾经通过将所需的消息保存到bean的属性,然后通过outputText显示属性来解决类似的问题:
<h:outputText
value="#{CreateNewPasswordBean.errorMessage}"
render="#{CreateNewPasswordBean.errorMessage != null}" />
答案 5 :(得分:1)
谷歌搜索时发现this。第二篇文章指出了JSF的不同阶段,这可能导致您的错误消息丢失。另外,尝试null代替“newPassword”,因为你没有任何id为newPassword的对象。
答案 6 :(得分:1)
我试过这个是最好的猜测,但没有运气:
看起来对我来说。您是否尝试过明确设置消息严重性?另外我认为ID必须与组件的ID相同(即,如果这些是你的ID,你需要使用newPassword1或newPassword2,而不是像示例中那样使用newPassword。)
FacesContext.getCurrentInstance().addMessage("newPassword1",
new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Message"));
然后使用<h:message for="newPassword1" />
在JSF页面上显示错误消息。
答案 7 :(得分:0)
简单回答,如果您不需要将其绑定到特定组件......
爪哇:
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Authentication failed", null);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, message);
XHTML:
<h:messages></h:messages>