FullAjaxExceptionHandlerFactory似乎工作,但它不显示登录屏幕。知道为什么吗?

时间:2014-01-13 20:17:45

标签: jsf omnifaces

我正在尝试在tomcat上使用FullAjaxExceptionHandlerFactory。我的WEB-INF / lib包含

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

我的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>

我的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>  
(...)

我的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>

和我的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;
    }

}

到达页面后,我只关闭并重新启动服务器,因此视图已过期并单击“保存”。

我的firebug说异常处理程序正确地重定向到登录,但页面内容永远不会显示。请参见下面的屏幕截图(红色区域)。

screenshot

错误页面与omnifaces页面(http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler

相同

1 个答案:

答案 0 :(得分:1)

  

我正在使用SerlvetFilter检查是否存在某个特定会话对象以检查用户是否已登录。

你不应该做

response.sendRedirect("login.xhtml");

关于ajax请求。 HTTP流量监视器指示您正在执行的302条目。您基本上是将ajax请求重定向到资源,而该资源根本不会返回有效的ajax响应。作为有效的ajax响应,您应该返回一个特定的XML结构,这反过来又指示JSF的JavaScript中的ajax引擎执行window.location = newurl;

基本上:

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);
}

另见: