【问题标题】:JSF 2 - View Parameter validation and redirectionJSF 2 - 查看参数验证和重定向
【发布时间】:2011-09-07 07:16:23
【问题描述】:

我们正在使用 JSF 2 + Primefaces + Glassfish + CDI/WELD 进行开发。 我们的 search.xhtml 页面上有一个图书列表的 datalist/dataTable,每个都呈现为一个 outputLink。单击任何条目时,view.xhtml 将显示所有书籍详细信息。这是我们调用的 search.xhtml 中的代码:

<h:outputLink value="${request.contextPath}/viewBook.xhtml?id=${book.id}">${book.title} 
</h:outputLink> 

在 viewBook.xhtml 中,根据 URL 中传入的 book Id,在渲染页面之前填充详细信息,如下所示:

<f:metadata>
    <f:viewParam name="id" value="#{bookBean.id}"/>     
        </f:viewParam>
    <f:event type="preRenderView" listener="#{bookBean.populate}" />
</f:metadata>

我们的要求是在渲染页面之前验证 Id,如果我们的数据库中不存在,我们需要将其重定向到错误页面或在同一页面(即搜索页面)上显示错误消息

我们尝试以两种不同的方式验证图书 ID: 1.在populate方法中使用validation如下

if (bookFound)
{
    //Display details
}
else
{
    FacesContext fc = FacesContext.getCurrentInstance();
    fc.addMessage("id", new FacesMessage("No such book found in the system. Please try again."));
    fc.renderResponse();
}
  1. 通过在 view.xhtml 中挂钩自定义验证器并在屏幕上抛出验证器异常(Faces 消息)。我们使用 CDI-WELD,所以我们可以使用注入。

    <f:metadata>
        <f:viewParam name="id" value="#{bookBean.id}"/>
       <f:validator validatorId="bookIdValidator"/>
        </f:viewParam>
        <f:event type="preRenderView" listener="#{bookBean.populate}" />
    </f:metadata>
    

这两种方法都有效,但它们会在视图屏幕上显示错误,而不是在搜索屏幕上。可以使用代码将其重定向到错误页面:

FacesContext.getCurrentInstance().getExternalContext().redirect("/error.xhtml");
  1. 有没有办法处理验证,以便在单击 outputLink 的搜索页面上显示错误消息。我们知道我们需要处理搜索页面上的验证,但是如何将验证器与 h:outputLink 相关联。我们可以使用 h:link 替代吗(我们需要使用 GET 请求,而不是 POST..所以使用 commmandLink 或 Button 是不可行的)
  2. 有没有比我们现在做的更好的方法来重定向到错误页面。

    (FacesContext.getCurrentInstance().getExternalContext().redirect("/error.xhtml");)

任何指针将不胜感激。

感谢和问候

【问题讨论】:

    标签: validation jsf-2 redirect


    【解决方案1】:

    听起来您遇到的问题是您正在一个页面上创建 FacesMessage,但又希望将其显示在另一个页面上。您需要将 FacesMessage 存储到用户会话中(或者可能是较短的生命周期,如果可用),然后将其拉出到您希望它显示的页面上。

    有一些自动化的尝试:

    JSF 2 中有一个 Flash 作用域和一个方法 setKeepMessages。你可以试试这个,但我运气不太好。

    这里讨论了复制粘贴阶段监听器解决方案:http://ocpsoft.com/java/persist-and-pass-facesmessages-over-page-redirects/

    跨重定向显示消息也是 Seam 3 的一个功能。

    【讨论】:

      【解决方案2】:

      格卡里,

      您可以使用 JSF 进行导航吗?我不熟悉 WELD,但纯 JSF 解决方案可能会按如下方式工作。这假设您有一个名为 bookBean 的支持 bean。它应该有一个名为id 的属性,带有一个getter (getId) 和setter (setId)。

      1. 在您的支持 bean 中创建一个空白方法。它必须不带参数并返回一个字符串。

        String viewBook() {
            // We'll fill this in later.
            return "success";
        }
        
      2. 将您的h:outputLink 更改为h:commandLink,这会调用新方法:

        <h:commandLink action="#{bookBean.viewBook}" />
        
      3. 当链接被激活时,使用设置 bookBean 的 id 属性的操作更新链接:

        <h:commandLink action="#{bookBean.viewBook}">
            <f:setPropertyActionListener
                target="#{bookBean.id}"
                value="#{book.id}" />
        </h:commandLink>
        
      4. 更新支持 bean 中的新方法以进行所需的验证,并返回一个指示成功或失败的字符串:

        String viewBook() {
            String result;
        
            if (bookIdIsValid (this.getId()) {
                result = "success";
            } else {
                result = "error";
            }
        
            return result;
        }
        
      5. 在 faces-config.xml 中创建导航规则以路由到正确的目标,具体取决于结果代码:

        <navigation-rule>
            <from-view-id>/search.xhtml</from-view-id>
            <navigation-case>
                <from-action>#{bookBean.viewBook}</from-action>
                <from-outcome>success</from-outcome>
                <to-view-id>/viewBook.xhtml</to-view-id>
            </navigation-case>
            <navigation-case>
                <from-action>#{bookBean.viewBook}</from-action>
                <from-outcome>error</from-outcome>
                <to-view-id>/error.xhtml</to-view-id>
            </navigation-case>
        </navigation-rule>
        

      这允许支持 bean 向 JSF 指示结果,并且 JSF 库将处理重定向到适当的位置。

      【讨论】:

      • 您好 GargantuChet,感谢您的回复。虽然我们知道我们可以使用 commandButtons 和 commandLinks 来完成这项工作,但我们希望使用“GET”请求而不是“POSTS”。因此,输出链接。我们可以使用任何替代品吗?谢谢,gkari
      • 请问为什么需要 GET 而不是 POST?也就是说,您从使用 GET 中获得了哪些您希望保留的好处?
      猜你喜欢
      • 2012-07-27
      • 2020-06-05
      • 1970-01-01
      • 2011-07-21
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 2011-07-19
      相关资源
      最近更新 更多