问题描述
在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错误代码时,JSF仍会处理第一页表达语言中定义的方法.
此行为使托管bean抛出NullPointerException和HTTP 500 ERRO代码.
我的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行为吗?还是提供某种形式来显示404错误页面而无需更改URL?
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中,您可以使用<f:viewAction>
.
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:metadata>,< f :viewParam>和< 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验证器一起使用,并通过OmniFaces <o:viewParamValidationFailed>
.
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调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!