【问题标题】:Validating JSF view parameter and error message验证 JSF 视图参数和错误消息
【发布时间】:2012-07-27 10:06:13
【问题描述】:

我有一个 JSF2 页面,其中包含必须在数据库中查找的视图参数。 然后在页面上显示该实体的属性。

现在我想处理视图参数丢失/无效的情况

<f:metadata>
    <f:viewParam name="id" value="#{fooBean.id}" />
    <f:event type="preRenderView" listener="#{fooBean.init()}" />
</f:metadata>

init()的代码如下:

String msg = "";
if (id == null) {
    msg = "Missing ID!";
}
else {
    try {
        entity = manager.find(id);
    } catch (Exception e) {
        msg = "No entity with id=" + id;
    }
}
if (version == null) {
    FacesUtils.addGlobalMessage(FacesMessage.SEVERITY_FATAL, msg);
    FacesContext.getCurrentInstance().renderResponse();
}

现在我的问题是,remaing 页面仍在呈现,我在应用程序服务器日志中收到错误,指出实体为空(因此某些元素未正确呈现)。 我只想显示错误消息。

我是否应该返回一个字符串以便发出一个指向错误页面的POST? 但是,如果我选择这种方式,如何添加自定义错误消息?将字符串作为视图传递 参数似乎根本不是一个好主意。

【问题讨论】:

    标签: jsf-2


    【解决方案1】:

    在我看来,在这些情况下最好的做法是发送带有适当错误代码的 HTTP 响应(404 表示未找到/无效,403禁止等):

    将此实用方法添加到您的 FacesUtils:

    public static void responseSendError(int status, String message)
                               throws IOException {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.getExternalContext().responseSendError(status, message);
        facesContext.responseComplete();
    }
    

    然后,将您的 preRenderView 侦听器更改为:

    public void init() throws IOException {
        if (id == null || id.isEmpty()) {
            FacesUtils.responseSendError(404, "URL incomplete or invalid!");
        }
        else {
            try {
                entity = manager.find(id);
            } catch (Exception e) { // <- are you sure you want to do that? ;)
                FacesUtils.responseSendError(404, "No entity found!");
            }
        }  
    }
    

    【讨论】:

    • 非常好的和干净的解决方案。会多次调用 init(),还是 responseSendError() 会阻止这种情况?
    • 嗯,init() 仅在您每次访问您声明为preRenderView 侦听器的 XHTML 页面时调用一次。如果您回发到同一页面(例如单击h:commandButton),实际上会再次调用它。您可以阻止代码在其中的回发上执行,包装为:if (!FacesContext.getCurrentInstance().isPostback()){ /* stmts go here... */ }
    • 不确定我是否回答了您的问题...如果您想知道在执行responseSendError() 后是否会再次调用init(),答案是否定的。除非您正在寻找麻烦并创建了一个自定义错误页面来声明相同的侦听器。 :)
    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2019-04-06
    • 2012-05-11
    • 2017-10-19
    • 1970-01-01
    • 2012-05-09
    相关资源
    最近更新 更多