FullAjaxExceptionHandlerFactory seems to work, but it does not show the login screen. Any idea why?

StackOverflow https://stackoverflow.com/questions/21100554

  •  27-09-2022
  •  | 
  •  

Question

I am trying to use FullAjaxExceptionHandlerFactory on tomcat. My WEB-INF/lib contains

  • all-themes-1.0.10.jar
  • commons-io-2.4.jar
  • omnifaces-1.7.jar
  • primefaces-4.0.jar

My faces-config

<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">

    <navigation-rule>
        <navigation-case>
            <from-outcome>authSuccess</from-outcome>
            <to-view-id>/private/main.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

<factory>
    <exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>

</faces-config>

My webapp web.xml

(...)
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
<filter>
    <filter-name>facesExceptionFilter</filter-name>
    <filter-class>org.omnifaces.filter.FacesExceptionFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>facesExceptionFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>  
(...)
<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/expired.xhtml</location>
</error-page>
<error-page>
    <exception-type>java.sql.SQLException</exception-type>
    <location>/database.xhtml</location>
</error-page>
<error-page>
    <exception-type>java.lang.RuntimeException</exception-type>
    <location>/bug.xhtml</location>
</error-page>  
(...)

my xhtml

<h:form id="form">
    <p:spacer height="10" />
    <p:fieldset legend="Your information">
    <p:panel id="yourInfo">
    <h:panelGrid columns="2">
        <p:outputLabel for="username" value="User:" style="width:100px;"/>
        <p:outputLabel id="username" value="#{mainMB.username}"/>

        <p:outputLabel for="last" value="Last Update:" style="width:100px;"/>
        <p:outputLabel id="last" value="#{mainMB.lastUpdate}"/>

        <p:outputLabel for="text" value="Text:" style="width:100px;"/>
        <p:inputText id="text" value="#{mainMB.text}"/>
        <p:commandButton value="Save" action="#{mainMB.save}" update="form"/>
    </h:panelGrid>
    </p:panel>
    </p:fieldset>
</h:form>

and my MB

import java.io.Serializable;
import java.util.Date;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class MainMB implements Serializable {

    private static final long   serialVersionUID    = 1L;

    private String username;

    private String text;

    private Date lastUpdate;

    @EJB
    private MainEJB mainEJB;

    @PostConstruct
    public void init(){
        System.out.println("MB init");
        mainEJB.addNewUser();
        UserPoc u = mainEJB.getLatestUser();
        this.username = u.getName();
    }

    public void save(){
        this.lastUpdate = new Date();
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

}

after reaching the page, I just shutdown and restart the server, so the view is expired and click on "save".

My firebug says that the exception handler correctly redirects to login, but the page content never is shown. See the screenshot below (red area).

screenshot

error pages are the same as the omnifaces page (http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler)

Was it helpful?

Solution

I am using a SerlvetFilter to check if some specific session object is present to check if a user is logged in or not.

You should not do

response.sendRedirect("login.xhtml");

on an ajax request. The HTTP traffic monitor indicates with the 302 entry that you were doing that. You're basically redirecting the ajax request to a resource which doesn't return a valid ajax response at all. You should instead return as a valid ajax response a specific XML structure which in turn instructs JSF's ajax engine in JavaScript to do a window.location = newurl;.

Basically:

String loginURL = request.getContextPath() + "/login.xhtml";
boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request"));

if (ajaxRequest) {
    response.setContentType("text/xml");
    response.setCharacterEncoding("UTF-8");
    response.getWriter()
        .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
        .append("<partial-response>")
        .printf("<redirect url=\"%s\"></redirect>", loginURL)
        .append("</partial-response>");
}
else {
    response.sendRedirect(loginURL);
}

See also:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top