I'm starting from What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
I have a pre render view event listener:
<f:metadata>
<f:event type="preRenderView" listener="#{loginBean.performWeakLogin()}" />
</f:metadata>
which invokes the following method:
public String performWeakLogin() {
FacesContext facesContext = FacesContext.getCurrentInstance();
String parameter_value = (String) facesContext.getExternalContext().getRequestParameterMap().get("txtName");
if (parameter_value != null && parameter_value.equalsIgnoreCase("pippo")) {
try {
return "mainPortal";
} catch (IOException ex) {
return null;
}
} else {
return null;
}
}
and the following navigation rule:
<navigation-rule>
<from-view-id>/stdPortal/index.xhtml</from-view-id>
<navigation-case>
<from-outcome>mainPortal</from-outcome>
<to-view-id>/stdPortal/stdPages/mainPortal.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
However, it doesn't perform the navigation. It works when I use a command button as follows:
<p:commandButton ... action="#{loginBean.performWeakLogin()}" />
Navigation based on a method's return value is only performed by components implementing ActionSource2
interface and providing an attribute taking a MethodExpression
for that, such as action
attribute of UICommand
components, which is queued during Apply Request Values phase and invoked during Invoke Application phase.
The <f:event listener>
is merely a component system event listener method, not an action method. You need to perform the navigation manually as follows:
public void performWeakLogin() {
// ...
FacesContext fc = FacesContext.getCurrentInstance();
fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "mainPortal");
}
Alternatively, you can also send a redirect on a given URL, which is more useful for the case you don't want to navigate internally, but externally:
public void performWeakLogin() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/stdPortal/stdPages/mainPortal.xhtml");
}
Unrelated to the concrete problem, a servlet filter is a better place for the job of performing request based authorization/authentication.
I use JBoss 7 with JSF 2.1. The solution from BalusC was redirecting to the JBoss default error page, even though I had already set the default error page in the web.xml
<error-page>
<error-code>404</error-code>
<location>/myapp/404.xhtml</location>
</error-page>
To redirect to my own error page, I used the response to send the error:
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)facesContext.getExternalContext().getResponse();
try {
response.sendError(404);
} catch (IOException ioe) {
ioe.printStackTrace();
}
facesContext.responseComplete();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With