3

我有一个具有以下方法的 ViewScoped bean:

public Item getItem()  
{
     try {
          itemID = Integer.parseInt(
             FacesContext.getCurrentInstance().getExternalContext()
                         .getRequestParameterMap().get("itemID"));  
     } catch(NumberFormatException ex) {
          FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                       FacesMessage.SEVERITY_ERROR, "Item lookup error", null));
          return null;  
     }  
     return itemsDAO.findByID(itemID);
}

该方法采用 ViewID 参数并使用itemsDAO. 如果 itemID 不是整数,我想通过捕获NumberFormatException并在其中添加消息来显示 FacesMessage。然而,这不起作用。上面的FacesMessage代码片段中的不呈现在下面的视图标签内h:messages globalOnly="true" infoClass="info" errorClass="error"

我怀疑在FacesContext调用该方法时它不可用,但我不知道如何处理这个异常。

更新1:

关于使用 viewParam 使用内置转换和验证的建议。我不知道在这种情况下这将如何工作。itemID 是从“索引”视图传递的,其中列出了所有项目,如下所示。每个项目标题都是指向 viewItem 页面的链接,其中 itemID 通过 URL 传递。鉴于索引视图有很多项目,在这种情况下,如何使用 viewParam 将 itemID 传递给 viewItem 视图?

索引.xhtml

<code>
 <ui:repeat var="item" value="#{ItemViewBean.items}">
       <div id="item">
        <h:link value="#{item.title}" outcome="viewItem">
        <f:param name="itemID" value="#{item.id}"></f:param>
        </h:link>
        <p><h:outputText value="#{item.description}"></h:outputText> <br />
        Address: <h:outputText value="#{item.address}"></h:outputText></p>
        <span class="itemFooter">
        Submitted By: <h:outputText value="#{item.user.username}"></h:outputText> On
        <h:outputText value="#{item.postDate}"></h:outputText>
        </span>
       <hr />
       </div>
       </ui:repeat>
</code>

更新 2:我想出了一个解决这个问题的方法。如果发生异常,我将错误 FacesMessage 放在 Flash 对象中并重定向到某个错误页面。我仍然不明白为什么不能简单地将 FacesMessage 添加到 FacesContext 并显示在视图上。

4

1 回答 1

3

鉴于您正在遍历ExternalContext#getRequestParameterMap(),您似乎正在拦截 GET 请求。鉴于它发生在 getter 方法中(糟糕!!),它似乎仅在item要呈现引用该属性的组件时执行。

因此,假设上述假设成立,那么当<h:messages>组件在视图中声明在引用该属性的组件之前,就会出现此问题。item然后将新消息添加到面孔上下文中为时已晚。那个<h:messages>时候已经渲染了。

我至少想不出与此特定问题症状相匹配的其他合理原因。该问题基本上有2个解决方案:

  1. <h:messages>移到引用该属性的组件之后item,以便在添加 faces 消息后呈现它。

  2. 在预渲染视图事件期间执行业务作业<f:event>,最好结合<f:viewParam>将请求参数设置为 bean 属性。<f:viewParam>鉴于您的不良吸气剂方法的唯一工作是转换价值,您甚至可以单独使用 a与转换器组合。

不用说选项 2 是首选,因为您目前基本上在滥用/解决一些基本的 JSF 概念。其中,业务逻辑不属于 getter。

例如

<f:metadata>
    <f:viewParam id="itemID" name="itemID" value="#{bean.item}"
        required="true" requiredMessage="Invalid page access. Please use a link from within the system."
        converter="itemConverter" converterMessage="Unknown item ID."
    />
</f:metadata>
<h:message for="itemID" />

private Item item; // +getter +setter

itemConverter只是一个Converter实现,其中请求参数被转换为方法中的Item实例getAsObject()

也可以看看:

于 2013-01-06T23:29:05.687 回答