In my web app, when the session expires and a user initiates a request (full page or AJAX), the user is redirected to the login page with a message that the session expired. The problem is, when the login page is left open long enough for the session to expire and the user attempts to login, the user is redirected to the login page with a message that the session expired.
I came across this solution, but it is for JSF 1.x and won't work with JSF 2. So I started building my own:
public class LoginViewHandler extends ViewHandler
{
public LoginViewHandler(ViewHandler parent)
{
this.parent = parent;
}
@Override
public Locale calculateLocale(FacesContext context)
{
return parent.calculateLocale(context);
}
@Override
public String calculateRenderKitId(FacesContext context)
{
return parent.calculateRenderKitId(context);
}
@Override
public UIViewRoot createView(FacesContext context, String viewId)
{
return parent.createView(context, viewId);
}
@Override
public String getActionURL(FacesContext context, String viewId)
{
return parent.getActionURL(context, viewId);
}
@Override
public String getResourceURL(FacesContext context, String path)
{
return parent.getResourceURL(context, path);
}
@Override
public void renderView(FacesContext context, UIViewRoot viewToRender)
throws IOException, FacesException
{
parent.renderView(context, viewToRender);
}
@Override
public UIViewRoot restoreView(FacesContext context, String viewId)
{
UIViewRoot viewRoot = parent.restoreView(context, viewId);
if (viewRoot == null && viewId.equals("/login.xhtml"))
{
parent.initView(context);
viewRoot = parent.createView(context, viewId);
context.setViewRoot(viewRoot);
try
{
buildView(context, viewRoot); // Compile error!
}
catch (IOException e)
{
log.log(Level.SEVERE, "Error building view", e);
}
}
return viewRoot;
}
@Override
public void writeState(FacesContext context) throws IOException
{
parent.writeState(context);
}
private ViewHandler parent;
}
However, there is no method called buildView
. I'm not sure what it does, why it's needed and what I should replace it with. Any ideas?
It has been moved to ViewDeclarationLanguage#buildView()
as this step is decoupled from the view technology used (Facelets, JSP, JavaVDL, whatever).
context.getApplication().getViewHandler()
.getViewDeclarationLanguage(context, viewId).buildView(context, viewRoot);
It's by the way simpler to extend ViewHandlerWrapper
instead. This way you don't need that bunch of delegate methods.