Using Navigation in JSF
Framework: JSF 2.0.
My problem: I have a page, called login.xhtml. Whenever someone view that page, it invoked a filter, called Authentication filter. The filter will check, if user already loged in, it will be redirected to default based on user's role (for example: Admin will go to "admin/admin.xhtml", student will be redirected to "user/user.xhtml").
My solution: Using the JSF Navigation
My config:
faces-config.xml
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>AD</from-outcome>
<to-view-id>/admin/admin.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>US</from-outcome&g开发者_C百科t;
<to-view-id>/user/user.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
The redirection using navigation:
public static void redirectUsingNavigation(String from, String outCome) {
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, from, outCome);
}
My question:
- When i run the redirectUsingNavigation("*","AD") or redirectUsingNavigation(null,"AD"), it does not redirect me to admin.xhtml (i'm still on login.xhtml). How to fix this?
- Any framework support me on this problem?
That code is not redirecting at all. It's just forwarding the request. It's just using the same request object for a different target page). A real redirect instructs the browser to send a new request on the given Location
header. You see this change being reflected back in browser address bar.
You need to either add faces-redirect=true
parameter to the outcome to trigger the redirect (this is particularly useful if you're using implicit navigation instead of verbose navigation cases):
navigationHandler.handleNavigation(facesContext, from, outCome + "?faces-redirect=true")
Or add <redirect/>
to the navigation cases if you want them to always take place:
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>AD</from-outcome>
<to-view-id>/admin/admin.xhtml</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-outcome>US</from-outcome>
<to-view-id>/user/user.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
Last but not least, you need to ensure that handleNavigation()
is called before the response is committed, otherwise it won't work at all and your server logs would be littered with IllegalStateException: response already committed
errors. You can make use of <f:event type="preRenderView">
to invoke a bean action before the response is committed.
See also:
- jsf navigation question
- Hit a bean method and redirect on a GET request
精彩评论