Browser Refresh handling in JSF
Is there a way i can handle browser refreshes event inside my JSF 2.0 application so that the user be navigated to the welcome page when a browser refreshes the page? and that leads me to another question of how to make page navi开发者_如何学Gogation inside managed bean?
Cheers,
Use a single view wherein you conditionally render includes.
<h:panelGroup id="body">
<ui:include src="#{bean.page}.xhtml" />
</h:panelGroup>
Make the bean view scoped and use commandlinks with <f:ajax>
to change the included page.
<h:form>
<h:commandLink value="Page 1" action="#{bean.setPage('page1')}">
<f:ajax execute="@this" render=":body" />
</h:commandLink>
<h:commandLink value="Page 2" action="#{bean.setPage('page2')}">
<f:ajax execute="@this" render=":body" />
</h:commandLink>
</h:form>
If you set the welcome page as default include page during bean's (post)construction, then a fresh new GET request will always show the welcome page. The only disadvantage is that those pages are not bookmarkable anymore, but that doesn't seem to be a major concern given this particular functional requirement.
Not really.
There is nothing for that in http protocol or in jsf.
You could find some "hack" (numbering your requests), but I think it would be complicated at best.
If a client asked me something like it, I'd let it pay a lot for the feature, without too much guarantees. It looks like an unrealistic requirement to me ;-)
I solved reloading page issue using next approach.
Phase listener
for phase RENDER_RESPONSE
is created NavigateHomePage
.
On every page which requires browser reloading should navigate to "Home page" is added f:phaseListener
with type = "my.NavigateHomePage"
.
NavigateHomePage
in method afterPhase
defines current page name (from request
path) and stores it in session
.
NavigateHomePage
in method beforePhase
defines current page name (from request
path), takes previous page name from session
and takes request method
. If current page name equals to previous page name and request method
is GET
and current page is not "Home page" then redirect to "Home page" is done.
The limitation is that for such pages (browser reloading of which navigates to "Home page") there should not be links (via GET
) to itself.
To include phase listener to page add in page next:
<f:phaseListener type="my.NavigateHomePage"/>
Phase listener
code is next:
public class NavigateHomePage implements PhaseListener {
private static final String CURR_PAGE = "currPage";
private static final String HOME_PAGE = "home";
private static final String HOME_PATH = "/my/faces/home.xhtml";
@Override
public void afterPhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
String currPage = getPageName(facesContext);
facesContext.getExternalContext().getSessionMap().put(CURR_PAGE, currPage);
}
@Override
public void beforePhase(PhaseEvent event) {
//check browser reload and redirect to Main page
FacesContext facesContext = event.getFacesContext();
String requestMethod = ((HttpServletRequest)facesContext.getExternalContext().getRequest()).getMethod();
String currPage = (String) facesContext.getExternalContext().getSessionMap().get(CURR_PAGE);
String newPage = getPageName(facesContext);
if ("GET".equals(requestMethod) && newPage.equals(currPage) && !HOME_PAGE.equals(newPage)) {
try {
facesContext.getExternalContext().redirect(HOME_PATH);
} catch (IOException ex) {
Logger.getLogger(this.getClass()).warn("Can't redirect to Home page", ex);
}
}
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
private String getPageName(FacesContext facesContext) {
String pagePath = facesContext.getExternalContext().getRequestServletPath();
String pageName = pagePath.substring(pagePath.lastIndexOf("/") + 1, pagePath.lastIndexOf(".xhtml"));
return pageName;
}
}
精彩评论