In my app I have JSF page with some parameters
(url of example page: /pages/user.xhtml?id=123&userToShowId=2
)
On this page i have a commandButton
. After click it I want to redirect to the same page with all parameters. I know, that for this specified page I can do this manually this way:
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");
}
But what to do when I want to get universal way to redirect from any page with any parameters?
If I have view parameters only at pages, without set it as a bean property:
<f:metadata>
<f:viewParam name="backurl"/>
<f:viewParam name="id"/>
</f:metadata>
not with value
:
<f:metadata>
<f:viewParam name="backurl" value=#{bean.id}/>
<f:viewParam name="id" value=#{bean.id}/>
</f:metadata>
can I use includeViewParams=true
to do my work?
You can do it without having to bind them to the managed bean. In JSF there are two main navigation cases:
h:button
, which doesn't need to be wrapped by a form and acts like a link.h:commandButton
.You can include view params in both cases. That's how it's done:
<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";
}
}
You'll see when you initially load the page, both backurl
and id
don't have a value.
The first button performs a GET request with fixed view parameter values. When view loads again, values are already there. Second button does the same but using an action method.
Keep in mind that using @RequestScoped
or @ViewScoped
here has the same effect, as @RequestScoped
doesn't maintain the state of the bean and @ViewScoped
destroys it each time an String
value is returned from the method, which is happening every time we invoke it.