我有一个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视图?
的index.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并显示在视图上。
答案 0 :(得分:3)
鉴于您正在遍历ExternalContext#getRequestParameterMap()
,您似乎正在拦截GET请求。鉴于它发生在getter方法(bad!!)中,它似乎只在要呈现引用item
属性的组件时执行。
因此,假设上述假设为真,那么在引用<h:messages>
属性的组件之前在视图中声明item
组件时,就会出现此问题。 。然后,在面部上下文中添加新消息为时已晚。 <h:messages>
就在那时,已经呈现。
我至少可以不考虑与此特定问题症状相匹配的其他合理原因。该问题基本上有两种解决方案:
在引用<h:messages>
属性的组件之后将item
移动到,以便在 faces消息之后呈现已被添加。
在<f:event>
的预渲染视图事件期间执行业务作业,最好与<f:viewParam>
结合使用,将请求参数设置为bean属性。你甚至可以单独使用<f:viewParam>
与转换器结合使用,因为你的糟糕的getter方法的唯一工作就是转换价值。
不用说选项2是首选,因为您目前基本上滥用/解决了一些基本的JSF概念。其中业务逻辑不属于getter。
E.g。
<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()
实例。