【问题标题】:How to redirect to same page with all parameters?如何使用所有参数重定向到同一页面?
【发布时间】:2013-12-23 16:43:57
【问题描述】:

在我的应用中,我有带有一些参数的 JSF 页面

(示例页面网址:/pages/user.xhtml?id=123&userToShowId=2

在这个页面上我有一个commandButton。单击它后,我想使用所有参数重定向到同一页面。我知道,对于这个指定的页面,我可以通过这种方式手动执行此操作:

public String redirect(){
    //extCtx - ExternalContext
    //ctx - FacesContext
    Map<String,String> param = extCtx.getRequestParameterMap();
    String currentURL = ctx.getViewRoot().getViewId();
    return currentURL+"?userToShowId="+param.get("userToShowId")+"&id="+param.get("id");
}

但是,当我想获得从任何带有任何参数的页面重定向的通用方式时该怎么办?


如果我只在页面上查看参数,而不将其设置为 bean 属性:

<f:metadata>
    <f:viewParam name="backurl"/>
    <f:viewParam name="id"/>
</f:metadata>

不是value

<f:metadata>
    <f:viewParam name="backurl" value=#{bean.id}/>
    <f:viewParam name="id" value=#{bean.id}/>
</f:metadata>

我可以使用includeViewParams=true 来完成我的工作吗?

【问题讨论】:

  • 你的意思是你想在你的webapp整个的任何请求中盲目地包含视图请求参数?您将需要一个自定义导航处理程序
  • 我有命令按钮来更改所有页面的语言。当我单击此按钮时,我必须编写一些支持 bean 代码(以更改语言)并返回同一页面。但是当我点击按钮的页面上有一些参数时,在制作 bean 代码后我会丢失所有参数。
  • 看看this
  • @XtremeBiker 我看到了this,但我使用的是f:viewParam。你的意思是我必须将这个参数添加到 bean 中?

标签: jsf redirect jsf-2 parameters query-string


【解决方案1】:

您无需将它们绑定到托管 bean 就可以做到这一点。在 JSF 中有两种主要的导航案例:

  • 执行查看请求而无需执行更多操作。这是一个 HTTP GET 请求,使用 h:button 完成,它不需要被表单包装,就像一个链接。
  • 执行表单POST,然后请求另一个页面(REDIRECT-GET),这是由h:commandButton 完成的。

您可以在这两种情况下都包含视图参数。就是这样完成的:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core">
<h:head />
<h:body>
    <f:metadata>
        <f:viewParam name="backurl" />
        <f:viewParam name="id" />
    </f:metadata>
    <h:outputText value="backurl value is #{backurl} and id value is #{id}" />
    <br />
    <h:button outcome="index" value="redirect">
        <f:param name="backurl" value="directUrl" />
        <f:param name="id" value="directId" />
    </h:button>
    <h:form>
        <h:commandButton value="action" action="#{bean.redirect}" />
    </h:form>
</h:body>
</html>
@ManagedBean
@RequestScoped
// You could also use @ViewScoped
public class Bean implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * Performs a redirection to index destination view with the given params
     * 
     * @return
     */
    public String redirect() {
        return "index?backurl=actionUrl&id=actionId&faces-redirect=true";
    }
}

您会在最初加载页面时看到,backurlid 都没有值。

第一个按钮使用固定的视图参数值执行 GET 请求。当视图再次加载时,值已经存在。第二个按钮的作用相同,但使用了一个动作方法。

请记住,在这里使用@RequestScoped@ViewScoped 具有相同的效果,因为@RequestScoped 不会维护bean 的状态,并且@ViewScoped 会在每次返回String 值时销毁它方法,每次我们调用它时都会发生这种情况。

【讨论】:

  • 但是当我不知道参数名称但我想重新加载页面时该怎么办?
  • 我必须重定向到同一页面,没有其他页面。也就是说,我要刷新页面,不要丢失参数值。
  • h:button 的情况下,只需将您发送的固定值替换为#{backurl}#{id}。对于 action 方法,您可以将无参数的 #{bean.redirect} 更改为 #{bean.redirect(backurl,id)} 并使其在服务器端接收两个 String 参数(如果您使用的是 EL 2.2,则可以传递参数)。然后,使用接收到的参数执行重定向。
  • 我想用任何参数从任何页面重定向通用方法,所以我可以知道任何请求的参数吗?
  • 您需要事先了解目标视图的参数。显然,您可以将它们留空,但您需要为这种情况准备好目标视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多