当托管bean构造函数发送404错误代码时,JSF调用方法 [英] JSF calls methods when managed bean constructor sends 404 ERROR CODE

查看:134
本文介绍了当托管bean构造函数发送404错误代码时,JSF调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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中时,都应该绝对停止并查看该功能是否在

(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

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调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆