【问题标题】:JSF page validation in Java and generated component IDs issueJava 中的 JSF 页面验证和生成的组件 ID 问题
【发布时间】:2013-03-01 20:55:09
【问题描述】:

我根据<h:message for="" /> JSF 对象有一个问题。我有一个 JSF 1.1(是的,不幸的是)myFaces 项目。我准备了一个带有标签、inputText 和消息持有者的简单 JSP 文件:

<h:form id="sacLinkForm">
    <cblFaces:outputLabel for="dedicatedCashAccountNumber"
        value="#{appBundle.KUSTA_DEDICATED_CASH_ACCOUNT_NUMBER}"/>
    <t:inputText id="dedicatedCashAccountNumber"
        value="#{createController.modelFE.sacLink.dedicatedCashAccountNumber}"/>
    <h:message id="dedicatedCashAccountNumberError"
        for="dedicatedCashAccountNumber" />
</h:form>

我还创建了简单的验证方法:

public static boolean validate(SACLink link) {
    boolean isError = false;
    FacesContext context = FacesContext.getCurrentInstance();
    FacesMessage message = new FacesMessage();
    message.setSeverity(FacesMessage.SEVERITY_ERROR);

    if (StringUtils.isEmpty(link.dedicatedCashAccountNumber)) {
        //MessageUtils.addErrorMessage("dedicatedCashAccountNumber", "Dedicated Cash Account Number is mandatory");
        message.setSummary("Field mandatory");
        message.setDetail("Dedicated Cash Account Number is mandatory");
        context.addMessage("sacLinkForm:dedicatedCashAccountNumber", message);
        isError = true;
    }
    return !isError;
}

我的问题在于sacLinkForm:dedicatedCashAccountNumber,因为编译后的 JSP 生成了 id(例如 _idJsp12:DynTab2:DynView2:tabK.....er:vKustaMa....Controller:sacLinkForm:dedicatedCashAccountNumber),这可能导致 addMessage 方法与 h:message for=".." 属性不对应。

所以消息没有正确显示,因为 java 找不到正确的h:message 对象。有什么方法可以从 Java 将消息设置为正确的h:message?我假设没有办法在 JSF 1.1 页面中强制“恒定”组件 ID。

谢谢。

【问题讨论】:

  • 您是否尝试将 prependId="false" 添加到表单中?并使用 dedicatedCashAccountNumber 代替 sacLinkForm:dedicatedCashAccountNumber
  • @Laabidi: prependId 在 JSF 1.2 中引入。 OP 正在使用 JSF 1.1。
  • 抱歉,我确认了。我只是在检查(在怀疑之后)。甚至 prependId 在 JSF 1.1 中也不可用
  • 正如@BalusC 所写。在下一个 JSF 版本中添加了 prependId 和其他 Id 修饰符。 ://

标签: java jsp jsf myfaces


【解决方案1】:

您根本不应该在 JSF 操作方法中手动执行验证。您应该使用 JSF 内置的验证工具。您应该使用普通的 JSF Validator。您从中抛出的任何ValidatorException 都将最终出现在正确的消息组件中。

用以下类替换 validate() 方法:

public class AccountNumberValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (StringUtils.isEmpty(value)) {
            FacesMessage message = new FacesMessage();
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            message.setSummary("Field mandatory");
            message.setDetail("Dedicated Cash Account Number is mandatory");
            throw new ValidatorException(message);
        }
    }

}

faces-config.xml注册如下:

<validator>
     <validator-id>accountNumberValidator</validator-id>
     <validator-class>com.example.AccountNumberValidator</validator-class>
</validator>

在视图中使用如下:

<t:inputText id="dedicatedCashAccountNumber"
    value="#{createController.modelFE.sacLink.dedicatedCashAccountNumber}"
    validator="accountNumberValidator" />

就是这样。请注意,如果验证(或转换)失败,则不会调用 JSF 操作方法。也不需要无意义的isError 混乱。

【讨论】:

  • 感谢您的回复。我还在考虑为每个规则使用专用验证器。但我不想为每个新的验证规则创建新的验证器。但是您是对的,这绝对是有效且干净的解决方案。但我有点害怕一些更复杂的验证规则,比如 f.e.相关的表单字段(例如 startDate > endDate; checkbox == 选中然后另一个字段将被不同地验证)。但是我可以在大多数情况下在控制器中验证它们,将错误消息返回到错误摘要选项卡(而不是字段 h:message)并阻止进一步的进展。
  • 多字段验证在stackoverflow.com/questions/6282466/…中解释,如果你碰巧用过JSF2或者了解JSF2源代码,OmniFaces有几个开源解决方案,见左侧菜单底部的“验证器”部分: showcase.omnifaces.org
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
  • 2011-07-10
  • 2010-12-30
  • 1970-01-01
  • 2015-01-24
  • 1970-01-01
相关资源
最近更新 更多