【发布时间】:2014-09-03 04:54:30
【问题描述】:
在 JSF 托管 bean 构造函数中,我使用请求参数从数据库加载实体。有时,实体不在数据库中,我想显示其他带有 404 消息的 JSF (.xhtml) 页面。
这是托管 bean 的示例:
@ManagedBean(name = "someBean")
@RequestScoped
public class SomeBean implements Serializable {
private static final long serialVersionUID = 1L;
private SomeData someData;
public SomeBean() throws IOException {
someData = ... loads from database using JPA features
if(someData == null){
HttpServletResponse response = (HttpServletResponse) FacesContext
.getCurrentInstance().getExternalContext().getResponse();
response.sendError(404);
}
}
public SomeData getSomeData(){
return someData;
}
}
我对 web.xml 文件进行了类似的配置:
<error-page>
<error-code>404</error-code>
<location>/404.xhtml</location>
</error-page>
我有一个 JSF 页面来处理托管 bean 加载的实体。当实体存在时,我将在页面中使用它。像这样:
<h1>#{someBean.someEntity.name}</h1>
<h2>#{someBean.someEntity.description}</h2>
<ui:repeat value="#{someBean.someEntity.books}" var="book">
// ..........
</ui:repeat>
当托管成功加载数据时,上面的页面工作。
问题
当实体不存在并且我发送一个 404 ERROR CODE 时,JSF 仍然处理在第一页的表达式语言中定义的方法。
此行为使托管 bean 抛出 NullPointerException 和 HTTP 500 错误代码。
我的 404 错误页面没有被调用。我不知道为什么。
即使在数据库中找到实体并且 404 错误页面正常工作,我也会尝试发送 404 错误。
谁能解释这种 JSF 的行为到这种幸福的程度?或者提供某种形式来显示 404 错误页面而不更改 URL?
【问题讨论】:
-
什么服务器? FacesServlet 的 url 映射是什么?至少在 Wildfly 上似乎它在映射到 *.xhtml 时会起作用
-
我使用 Tomcat 7、Servlet 3.0 API 和 JSF 2.2。其他 jsf 2 版本中也存在该问题。
-
我使用 Tomcat 7、Servlet 3.0 API 和 JSF 2.2。该问题也出现在其他 jsf 2 版本中。我使用WELD CDI实现手册配置,但是没有WELD CDI的tomcat也出现这个问题。我尝试使用
FacesContext.getCurrentInstance().responseComplete();,什么也没有。根据 JSF 生命周期,我认为这种行为是正确的,但我无法理解。 -
我使用通常的 FacesServlet 映射 (
/faces/*),使用 PrettyFaces 将 URL 映射到 .xhtml 文件;工作正常,除了报告的问题。
没有 PrettyFaces 也会出现问题。