Given a <p:selectOneMenu>
as follows.
<f:metadata>
<f:viewParam name="id" value="#{testManagedBean.id}" converter="javax.faces.Long"/>
</f:metadata>
<p:selectOneMenu value="#{localeBean.language}" onchange="changeLanguage();">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="hi" itemLabel="Hindi" />
</p:selectOneMenu>
<p:remoteCommand action="#{testManagedBean.submitAction}"
name="changeLanguage"
process="@this"
update="@none"/>
The corresponding managed bean :
@ManagedBean
@RequestScoped
public final class TestManagedBean {
private Long id; //Getter and setter.
public TestManagedBean() {}
public String submitAction() {
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true&includeViewParams=true";
}
}
The parameter as indicated by <f:viewParam>
is optional. A page, for example is accessed using a URL as follows.
https://localhost:8181/Project-war/private_resources/Test.jsf
Since id
is an optional parameter, an empty parameter is attached to the URL (when a language is changed from <p:selectOneMenu>
), in case it is not supplied as follows.
https://localhost:8181/Project-war/private_resources/Test.jsf?id=
This should not happen. An empty parameter should not be appended, if it is not supplied and the URL should look like the first one.
Is there a way to prevent an empty parameter from being appended to the URL, when it is not passed?
This is only associated with the converter as specified with <f:viewParam>
- javax.faces.Long
.
If this converter is removed then, parameters are not appended to the URL, in case no parameters are supplied.
Although specifying a converter as demonstrated here is completely unnecessary, I have converters as shown below to convert an id
passed though the URL as a query-string parameter to a JPA entity.
@ManagedBean
@RequestScoped
public final class ZoneConverter implements Converter {
@EJB
private final SharableBeanLocal sharableService = null;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
long parsedValue = Long.parseLong(value);
if (parsedValue <= 0) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Message Summary", "Message"));
}
ZoneTable entity = sharableService.findZoneById(parsedValue);
if (entity == null) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_WARN, "Message Summary", "Message"));
}
return entity;
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Message Summary", "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value instanceof ZoneTable ? ((ZoneTable) value).getZoneId().toString() : "";
}
}
This converter is now required to be specified explicitly with <f:viewParam>
as follows.
<f:viewParam name="id"
value="#{testManagedBean.id}"
converter="#{zoneConverter}"
rendered="#{not empty param.id}"/>
And the associated managed bean needs to be changed as follows.
@ManagedBean
@RequestScoped
public final class TestManagedBean {
private ZoneTable id; //Getter and setter.
public TestManagedBean() {}
public String submitAction() {
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true&includeViewParams=true";
}
}
See Question&Answers more detail:
os