Yet another Java Developer.

JSF Developer living in Oklahoma City

Gallery

IMGP0159.JPG IMGP0066.JPG IMGP0149.JPG imgp0247-large.jpg

Preventing ViewExpiredException in JSF

When our page is idle for x amount of time the view will expire and throw javax.faces.application.ViewExpiredException to prevent this from happening
one solution is to create CustomViewHandler that extends ViewHandler
and override restoreView method all the other methods are being delegated to the Parent

import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
 
public class CustomViewHandler extends ViewHandler {
	private ViewHandler parent;
 
	public CustomViewHandler(ViewHandler parent) {
		//System.out.println("CustomViewHandler.CustomViewHandler():Parent View Handler:"+parent.getClass());
		this.parent = parent;
	}
 
    @Override public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
	/**
	 * {@link javax.faces.application.ViewExpiredException}. This happens only  when we try to logout from timed out pages.
	 */
	UIViewRoot root =null; 
	root = parent.restoreView(facesContext, viewId);
	if(root == null) {			
		root = createView(facesContext, viewId);
	}
	return root;
 }
 
 @Override
	public Locale calculateLocale(FacesContext facesContext) {
		return parent.calculateLocale(facesContext);
	}
 
	@Override
	public String calculateRenderKitId(FacesContext facesContext) {
		String renderKitId = parent.calculateRenderKitId(facesContext);
		//System.out.println("CustomViewHandler.calculateRenderKitId():RenderKitId: "+renderKitId);
		return renderKitId;
	}
 
	@Override
	public UIViewRoot createView(FacesContext facesContext, String viewId) {
		return parent.createView(facesContext, viewId);
	}
 
 
    @Override
	public String getActionURL(FacesContext facesContext, String actionId) {
		return parent.getActionURL(facesContext, actionId);
	}
 
	@Override
	public String getResourceURL(FacesContext facesContext, String resId) {
		return parent.getResourceURL(facesContext, resId);
	}
 
	@Override
	public void renderView(FacesContext facesContext, UIViewRoot viewId) throws IOException, FacesException {
		parent.renderView(facesContext, viewId);
 
	}
 
	@Override
	public void writeState(FacesContext facesContext) throws IOException {
		parent.writeState(facesContext);
	}
 
	public ViewHandler getParent() {
		return parent;
	}
 
}

Then you need to add it to your faces-config.xml

<view-handler>com.demo.CustomViewHandler</view-handler>

This will prevent you from getting ViewExpiredException’s

Tags: ,

11 Responses to “Preventing ViewExpiredException in JSF”

  1. Kashif Says:

    Hi, I am trying to implement this example but not sure where does the object ‘parent’ come from. Please help me.

    Regards,
    Kashif

  2. Greg Says:

    Parent comes from the ViewHandler constructor, also there are other methods that can be overwritten if you like.

    private ViewHandler parent;

    public CustomViewHandler(ViewHandler parent) {
    //System.out.println("CustomViewHandler.CustomViewHandler():Parent View Handler:"+parent.getClass());
    this.parent = parent;
    }

    Hope this helps, also I will update the post with this.

  3. Pepe Says:

    Hi I tried this example and I get failure. It is due to the spread of ViewHanler you add other methods that do not what to do with them. In asking that page shows me what I’m doing gives me an error java.lang.NullPointerException: renderKitId

    I’m a little awkward and not what you have to do. Please help.

  4. Greg Says:

    I have updated the example with the other overwritten methods that should fix your problem.
    If you still having issues post your code for your Custom ViewHandler

  5. Pepe Says:

    Thank you very much, Greg.

  6. Greg Says:

    No problem I hope this helps you.

  7. Amit Kumar Says:

    Great work man :). It is the simplest working solution. Thanks.

  8. Greg Says:

    Thanks

  9. Alex Says:

    If you’re using Facelets you can extend FaceletViewHandler and just have the restoreView() method. In my case I also return an error/information page if root == null. I think it’s more user friendly. Here’s the code:

    public class MyFaceletViewHandler extends FaceletViewHandler {
     
        public MyFaceletViewHandler(ViewHandler parent) {
            super(parent);
        }
     
        @Override
        public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
            UIViewRoot root = super.restoreView(facesContext, viewId);
            // do not allow ViewExpiredException
            if (root == null) {
                root = createView(facesContext, "/viewExpired.xhtml");
                facesContext.renderResponse();
            }
            return root;
        }
     
    }
  10. Romeo Says:

    Thanks for the solution. But I still do have some problems getting around my basic issue.
    I have a secured application (Spring security), with a simple login form. I can happen fairly often that the user opens the login page and leaves the browser open without performing a login.
    The session times out and when the user tries to login he would get a ViewExpiredException.
    Displaying a session-time-out-page makes no sense, the user was at the start page and overriding the ViewExpiredException-behaviour for this single, simple issue seems like a dangerous overkill for me.
    Is there any other way telling JSF this is the start page, we do not need a stored view for this??? I have read numerous articles about this and it has been bugging me for nearly a year(!) that you need to make fairly big changes in the JSF-ecosystem for imho a very, very common problem.
    Where am I wrong?

  11. Greg Says:

    You might want to use

     
        javax.faces.application.ViewExpiredException
        /sessionExpired.jsf

    in you faces-config.xml it might work for you. There is also a way of defining on how to catch errors in web.xml

Leave a Reply

Spam Protection by WP-SpamFree

Sidebar3 : Please add some widgets here.