问题描述
在 JSF 托管 bean 构造函数中,我使用请求参数从数据库加载实体.有时,实体不在数据库中,我想显示带有 404 消息的其他 JSF (.xhtml) 页面.
这是托管 bean 的示例:
In a JSF managed bean constructor, I load a entity from database usint a request parameter. Some times, the entity is not in database and I want to show other JSF (.xhtml) page with 404 message.
This is a sample of managed 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 文件:
I configured the web.xml file something like that:
<error-page>
<error-code>404</error-code>
<location>/404.xhtml</location>
</error-page>
我有一个 JSF 页面来处理托管 bean 加载的实体.当实体存在时,我将在页面中使用它.像这样:
I have a JSF page to handle the entity loaded by managed bean. When the entity exists, I will use it in the page. Like that:
<h1>#{someBean.someEntity.name}</h1>
<h2>#{someBean.someEntity.description}</h2>
<ui:repeat value="#{someBean.someEntity.books}" var="book">
// ..........
</ui:repeat>
当托管成功加载数据时,上述页面有效.
The page above works when the managed loads the data successfully.
当实体不存在并且我发送一个 404 ERROR CODE 时,JSF 仍然处理在第一页的表达式语言中定义的方法.
此行为使托管 bean 抛出 NullPointerException 和 HTTP 500 错误代码.
我的 404 错误页面没有被调用.我不知道为什么.
When the entity not exists and I send a 404 ERROR CODE, the JSF still process methods defined in the expression language of the first page.
This behavior makes the managed bean throws a NullPointerException, and a HTTP 500 ERRO CODE.
My 404 error page is not called. I do not know why.
即使在数据库中找到实体并且 404 错误页面有效,我也会尝试发送 404 错误.
I try send the 404 error even when the entity is found in database and the 404 error page works.
谁能把这种JSF的行为解释成这种幸福?或者提供某种无需更改 URL 即可显示 404 错误页面的方法?
Enyone can explain this JSF behavior to this happiness? Or offer some kind to show the 404 error page without URL change ?
推荐答案
您基本上是在尝试在渲染视图时执行前端控制器逻辑.您应该在渲染视图之前执行此操作.因为,一旦开始渲染视图,将视图更改为不同的目的地已经太晚了,例如与您的情况一样的错误页面.您即不能从客户端取回已经发送的响应.
You're basically trying to perform front controller logic while rendering the view. You should do it before rendering the view. Because, once you start rendering the view, it's already too late to change the view to a different destination, e.g. an error page as in your case. You namely cannot take the already sent response back from the client.
在 JSF 2.2 中,您可以为此使用 .
In JSF 2.2 you can use <f:viewAction>
for this.
<f:metadata>
<f:viewAction action="#{bean.init}" />
</f:metadata>
public void init() {
// ...
if (someCondition) {
context.getExternalContext().responseSendError(404, "some message");
context.responseComplete();
}
}
(请注意,每当您需要将 javax.servlet.*
类导入 JSF 支持 bean 时,您绝对应该停下来看看 ExternalContext
或其他如果您以正确的方式做事,请三思,例如,您可能需要一个 servlet 过滤器;另外请注意,您需要明确告诉 JSF 您已完成响应,否则它仍会尝试呈现视图)
(note that whenever you need to import javax.servlet.*
classes into your JSF backing bean, you should absolutely stop and look if the functionality isn't already available in ExternalContext
or otherwise think twice if you're doing things the right way, e.g. perhaps you needed a servlet filter; also note that you need to explicitly tell JSF that you've completed the response, otherwise it will still attempt to render the view)
在 JSF 2.0/2.1 中,您可以使用 <f:event type="preRenderView">
为此.另请参阅什么可以、和 <f:viewAction>用于?
In JSF 2.0/2.1 you can use <f:event type="preRenderView">
for this. See also among others What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
如果您实际上是在尝试验证 HTTP 请求参数并且碰巧使用 OmniFaces,则可以考虑将 <f:viewParam>
与真正的 JSF 验证器一起使用并控制 <f:viewParam>
code>sendError 与 OmniFaces 一>.
In case you're actually trying to validate a HTTP request parameter and you also happen to use OmniFaces, you may consider using <f:viewParam>
with a true JSF validator and control the sendError
with OmniFaces <o:viewParamValidationFailed>
.
这篇关于当托管 bean 构造函数发送 404 错误代码时 JSF 调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!