I have a few pages that needs a userId to work, thus the following code:
userpage.xhtml
Am I right that for solution 1 <f:ajax execute="@form" render="@form" />
to work one would also have to include something like
<f:param name="userId" value="#{userPageController.userId}"/>
inside the <h:commandButton>
?
Like it is described in https://stackoverflow.com/a/14026995/811046
When i search around, I get the impression that the view parameter should remain after a post thus reading userpage.jsf?userId=123, but this is not the case. What is really the intended behaviour?
This behaviour is correct. The <h:form>
generates a HTML <form>
element with an action URL without any view parameters. The POST request just submits to exactly that URL. If you intend to keep the view parameters in the URL, then there are basically 3 ways:
Bring in some ajax magic.
<h:commandButton action="#{userPageController.doAction}" value="post">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
This way the initially requested page and thus also the request URL in browser's address bar remains the same all the time.
If applicable (e.g. for page-to-page navigation), make it a GET request and use includeViewParams=true
. You can use <h:link>
and <h:button>
for this:
<h:button outcome="nextview?includeViewParams=true" value="post" />
However, this has an EL security exploit in Mojarra versions older than 2.1.6. Make sure that you're using Mojarra 2.1.6 or newer. See also issue 2247.
Control the generation of action URL of <h:form>
yourself. Provide a custom ViewHandler (just extend ViewHandlerWrapper) wherein you do the job in getActionURL().
public String getActionURL(FacesContext context, String viewId) {
String originalActionURL = super.getActionURL(context, viewId);
String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
return newActionURL;
}
To get it to run, register it in faces-config.xml
as follows:
<application>
<view-handler>com.example.YourCustomViewHandler</view-handler>
</application>
This is also what OmniFaces <o:form> is doing. It supports an additional includeViewParams
attribute which includes all view parameters in the form's action URL:
<o:form includeViewParams="true">
Update: obtaining the view parameters of the current view programmatically (which is basically your 2nd question) should be done as follows:
Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());
for (UIViewParameter viewParam : viewParams) {
String name = viewParam.getName();
Object value = viewParam.getValue();
// ...
}