0

I am pulling my hairs over it and i know it was discussed here millions times.. after reading dozens questions here regarding this topic and trying them.. result is still same, this exception is not handled and not redirected to my custom error page.

So first what i did i added this to my web.xml

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/errorpages/expired.xhtml</location>
</error-page>

and created this simple error page in path /errorpages/expired.xhtml

<ui:composition 
  template="/templates/common/base.xhtml" 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<ui:define name="title">DeviceRepair - Sesja Wygasła</ui:define>

<ui:define name="metas">
    <meta http-equiv="refresh" content="0;url=#{request.contextPath}/login.xhtml" />
</ui:define>

<ui:define name="content">
    <h1>Sesja wygasła..</h1>
    <h3>Zostaniesz wkrótce przekierowany do strony logowania.</h3>
    <p><a href="#{request.contextPath}/login.xhtml">
        Naciśnij tutaj jeżelili przekierowanie nie zaskoczyło lub jeżeli jesteś niecierpliwy
        <!--Click here if redirect didn't work or when you're impatient-->
    </a>.</p>
</ui:define>
</ui:composition>

It didnt worked.. so then I created custom exception handler like follows, factory

public class ExceptionHandlerFactory extends javax.faces.context.ExceptionHandlerFactory {

private javax.faces.context.ExceptionHandlerFactory parent;

public ExceptionHandlerFactory(javax.faces.context.ExceptionHandlerFactory parent) {
    this.parent = parent;
}

@Override
public ExceptionHandler getExceptionHandler() {
    ExceptionHandler result = parent.getExceptionHandler();
    result = new ViewExpiredExceptionHandler(result);
    return result;
}
}

and custom wrapper class

public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {

private ExceptionHandler parent;

public ViewExpiredExceptionHandler(ExceptionHandler parent) {
    this.parent = parent;
}

@Override
public ExceptionHandler getWrapped() {
    return this.parent;
}

@Override
public void handle() throws FacesException {
    for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents()
            .iterator(); i.hasNext();) {
        ExceptionQueuedEvent event = i.next();
        ExceptionQueuedEventContext context = 
                (ExceptionQueuedEventContext) event.getSource();

        Throwable t = context.getException();
        if (t instanceof ViewExpiredException) {
            ViewExpiredException vee = (ViewExpiredException) t;
            FacesContext facesContext = FacesContext.getCurrentInstance();
            Map<String, Object> requestMap = facesContext.getExternalContext()
                    .getRequestMap();
            NavigationHandler navigationHandler = facesContext.getApplication()
                    .getNavigationHandler();
            try {
                // Push some useful stuff to the request scope for use in the page
                requestMap.put("currentViewId", vee.getViewId());
                navigationHandler.handleNavigation(facesContext, null, "/errorpages/expired");
                facesContext.renderResponse();
            } finally {
                i.remove();
            }
        }
    }

    // At this point, the queue will not contain any ViewExpiredEvents. 
    // Therefore, let the parent handle them.
    getWrapped().handle();
}

}

and putted this to faces-config.xml

<factory>
    <exception-handler-factory>
        pl.blabla.devicerepair.exception.ExceptionHandlerFactory
    </exception-handler-factory>
</factory>

Then it still didnt worked, so i added this to web.xml

<context-param>
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
</context-param>

Still same result, so changed javax.faces.PROJECT_STAGE in web.xml from Development to Production.. and it just ate error without any redirecting.. so even worse.

I test it by setting this in my web.xml

<session-config>
    <session-timeout>
        1
    </session-timeout>
</session-config>

and after run web app, just wait 2 minutes, and click some command button. Thanks for any help.

Exception Screen

10101101
  • 193
  • 1
  • 13
  • Please exactly describe "didnt worked". What exactly happens instead? And please exactly describe "some command button". What exactly does it? (ajax or not?). All of this is already covered in https://stackoverflow.com/questions/3642919/javax-faces-application-viewexpiredexception-view-could-not-be-restored including links how to create a proper exception handler for Ajax requests. – BalusC Mar 29 '20 at 15:13
  • @BalusC Sorry for late response, it didnt worked cause this exception is not handled and not redirected to my custom error page. Instead it shows Apache MyFaces error page with stack trace etc. I followed Your post which You linked, but still couldnt get it working. I also updated my question with the page which shows when this exception occurs. – 10101101 Mar 29 '20 at 17:25
  • Doesnt matter if ajax or not, same result for both. – 10101101 Mar 29 '20 at 17:39
  • The screenshot is recognizable as MyFaces built-in error page which is by default shown when project stage is Development. You can disable it by setting `org.apache.myfaces.ERROR_HANDLING` context param to `false`. This should also be instructed in the link in the footer which says "Disabling error handling in MyFaces". Have you checked out it? – BalusC Mar 29 '20 at 18:19
  • Setting this parameter resulted in 404 could not find resource /errorpages/expired .. so i added in web.xml this: 404 /errorpages/404.xhtml .. but now it neither redirects to my custom page, neither shows default error message page.. xD – 10101101 Mar 29 '20 at 18:54

0 Answers0