【问题标题】:How to get query parameters in ExceptionHandler?ExceptionHandler中如何获取查询参数?
【发布时间】:2012-02-02 17:26:59
【问题描述】:

在我们的项目(JBoss 7.0.2JSF 2)中,我们致力于在用户导航期间捕获所有异常并将它们重定向到漂亮的错误页面的解决方案。

我使用了ExceptionHandler,灵感来自网上很多examplestutorials

我设法在没有太大困难的情况下实现了重定向功能:在ExceptionHandler.handle() 方法中,对于某些例外情况(视图/会话过期、未经身份验证的用户询问被拒绝的页面……)我在登录页面上重定向用户走过一段美好的时光

FacesContext.getCurrentInstance().getExternalContext().redirect(myRedirectPage);

带有一个包含原始 url base64 编码的附加查询参数,并且在成功验证后,我使用相同的重定向机制将用户发送回他们的页面。


问题在于 JSF 操作上的 ViewExpiredException,例如,当用户在其视图过期后单击任何按钮或链接,以及操作或 actionListener、同步或 ajax 样式,例如

<h:commandButton action="#{myBean.myAction}" value="do that" />

<h:commandLink value="do that too">
    <f:ajax render=":aZone" execute="@form" listener="#{myBean.myOtherAction}" />
</h:commandLink>

我无法在ExceptionHandler.handle() 方法中获取查询参数。

我尝试将我的参数放在 f:metadata 部分中,例如

<f:metadata>
    <f:viewParam name="myParam" value="#{myBean.myParam}" />
</f:metadata>

并将它们包含在操作中,因此在绑定到按钮操作的方法中我返回了

"myPage.xhtml?includeViewParams=true"

但它什么也没改变 :-/

我做错了吗?我应该在哪里找到查询参数?是在

FacesContext.getCurrentInstance().getExternalContext().getRequest()

** 更新 **

正如 cmets 中所说,视图参数在 ViewExpiredException 之后不再可用(实际上非​​常明显),因此参数将存储在其他地方(@BalusC 很快建议在请求范围内或通过 cookie)。

【问题讨论】:

    标签: exception-handling jsf-2 navigation


    【解决方案1】:

    请求参数由ExternalContext#getRequestParameterMap()提供。

    Map<String, String> params = externalContext.getRequestParameterMap();
    // ...
    

    或者,如果您的应用程序使用具有多个值的相同参数名称(&lt;h:selectManyXxx&gt; 组件通常就是这种情况),请改用ExternalContext#getRequestParameterValuesMap()

    Map<String, String[]> params = externalContext.getRequestParameterValuesMap();
    // ...
    

    请注意,这仅返回当前请求的参数,在回发的情况下不返回初始请求的参数。

    至于ExternalContext#getRequest(),如果JSF 应用程序在servlet 容器上运行,它会返回您需要转换的HttpServletRequest 实例,但您应该很少需要获取它。 ExternalContext,虽然遵循外观设计模式,但有很多方法委托给底层的原始 HTTP servlet 请求、会话和上下文。您最终希望在您的支持 bean 中使用 zero javax.servlet 导入。


    更新 根据您的评论,您实际上只想获取&lt;f:viewParam&gt; 注册的视图参数。您可以通过ViewMetadata#getViewParameters() 获取它们,其中您传递当前的UIViewRoot

    Collection<UIViewParameter> viewParameters = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());
    // ...
    

    【讨论】:

    • 有没有办法只在ExternalContext.getRequestParameterMap() 中找到viewParam,因为如果我记得清楚的话,这张地图包含所有参数(目前无法测试)?
    • 呃你只想要视图参数?这与查询参数不完全相同......我会更新答案。
    • 实际上从未听说过ViewMetadata :) 无论如何,我设法从中获取了 viewParams,但它们为空。也许,当我将我的 viewParam 链接到 ViewScoped bean 属性时,类似于 &lt;f:viewParam name="myParam" value="#{myViewScopedBean.myParam}"/&gt;,并且当我的代码到达 之后 ViewExpiredException 时,也许我想做的事情是不可能的?我的意思是,viewParam 值存储在 viewscoped bean 中,但是在我的视图过期后,我可能无法再访问它了。这是真的吗?如果是,有没有办法存储 viewParam 值以便在视图过期后仍然获取它?
    • 天啊,这绝对有道理!在ViewExpiredException 期间初始视图不可用。您需要寻找替代方法,可能是基于请求或 cookie。
    • 好吧,我会寻找另一种方式,这个功能现在不是我们的首要任务。如果我发现一些不错的东西,我会在这里回复并随时通知您。
    猜你喜欢
    • 2014-12-26
    • 2019-02-23
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多