2

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?

kuba44
  • 1,670
  • 9
  • 29
  • 56
  • Do you mean you want to blindly include view request parameters with any request *throughout* your webapp? You'll need a custom navigation handler for that – kolossus Dec 24 '13 at 08:45
  • I have commandButton to change language at all page. When I click this button I have to make some backing bean code (to change lang) and come back to the same page. But when there is some parameter at page where i click the button, after make bean code i lose every parameters. – kuba44 Dec 24 '13 at 10:49
  • Have a look at [this](http://stackoverflow.com/questions/20728072/pagination-on-jsf-using-get-parameters). – Xtreme Biker Dec 24 '13 at 11:50
  • @XtremeBiker i see [this](http://stackoverflow.com/questions/20728072/pagination-on-jsf-using-get-parameters), but i use `f:viewParam`. Do you mean I have to add this parameters to beans? – kuba44 Dec 27 '13 at 15:52

1 Answers1

1

You can do it without having to bind them to the managed bean. In JSF there are two main navigation cases:

  • Perform a view request without doing nothing more. That's an HTTP GET request and is done using h:button, which doesn't need to be wrapped by a form and acts like a link.
  • Perform a form POST and after that ask for another page (REDIRECT-GET), that's done by 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.

Xtreme Biker
  • 28,480
  • 12
  • 120
  • 195
  • but what can I do when I don't know parameter name but I want to reload page? – kuba44 Dec 27 '13 at 18:00
  • 1
    And I have to redirect to the same page, no other. In other word, I want to refresh page and don't lose parameter value. – kuba44 Dec 28 '13 at 10:05
  • Just replace the fixed values you're sending by `#{backurl}` and `#{id}` for the `h:button` case. For the action method, you can change the no-parametered `#{bean.redirect}` by `#{bean.redirect(backurl,id)}` and make it receive two `String` parameters at server side (if you're using EL 2.2, which makes possible passing parameters). Then, perform the redirection with that received parameters. – Xtreme Biker Dec 28 '13 at 11:08
  • 1
    I want to get universal way to redirect from any page with any parameters, so have can i know about parameters of any request? – kuba44 Dec 30 '13 at 17:15
  • You need to know about parameters of the destination view previously. Obviously, you can leave them empty, but you need the destination view to be prepared for that case. – Xtreme Biker Dec 30 '13 at 17:37
  • so i can't make action method to change language on any page (with some parameters too) and come back to same page with parameters? – kuba44 Dec 30 '13 at 17:49
  • Of course you can. Use f:view with the locale attribute and set it a parameter based value. – Xtreme Biker Dec 30 '13 at 20:11
  • i think you don't understand me: i have a lot of pages with deferents parameters and one template page with `h:commandButton` with `action` to session scope bean with method, where i set locale. For different pages i have different parameters, but to change language i always use same `h:commandButton`. So I can't add `f:param` to `h:commandButton` because I don't know what parameter i get for current page, am I right? – kuba44 Dec 30 '13 at 21:04
  • If main template includes the `f:view` bound to the session bean you don't need to receive parameters in your destination page at all. All page will inherit from that `f:view`, when pages are reloaded, the locale value will be changed, so don't need to pass it as a view parameter. I think you're mixing Session parameters with GET parameters in this case. If you want a more specifc answer please post another thread with a more elaborated question according to your problem, as you didn't mention neither templates or languages at all in your original one. I think my answer suits for the original. – Xtreme Biker Dec 31 '13 at 13:09