JSF 1.x 通用异常处理

Posted

技术标签:

【中文标题】JSF 1.x 通用异常处理【英文标题】:JSF 1.x generic exception handling 【发布时间】:2010-10-02 09:57:27 【问题描述】:

如果我的业务层出现异常(例如,我的 JDBC 连接 bean 中的 SQL 异常),我如何通过自定义消息将其传播到全局 error.jsp 页面?

【问题讨论】:

【参考方案1】:

JSF 1.x 不提供这种类型的任何隐式错误处理,尽管您可以使用导航规则重定向到错误页面(假设是表单发布)...

<navigation-case>
<description>
Handle a generic error outcome that might be returned
by any application Action.
</description>
<display-name>Generic Error Outcome</display-name>
<from-outcome>loginRequired</from-outcome>
<to-view-id>/must-login-first.jsp</to-view-id>
</navigation-case>

...或使用重定向...

FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
String url = extContext.encodeActionURL(extContext
        .getRequestContextPath()
        + "/messages.faces");
extContext.redirect(url);

我建议查看JSF specification 了解更多详情。

错误消息可以放在请求范围/会话范围/url参数上,随你喜欢。


假设一个 Servlet 容器,你可以使用通常的web.xml error page configuration。

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/errorPage.faces</location>
</error-page>

在您的支持 bean 中,您可以在 RuntimeExceptions 中包装并抛出已检查的异常。

一些 JSF 实现/框架会捕获这些错误(Apache MyFaces/Facelets),因此您必须configure them not to。

【讨论】:

这是一个很好的回答,我希望我能给你10分。【参考方案2】:

JSF 2 现在有一种处理异常的机制:

http://java.sun.com/javaee/6/docs/api/javax/faces/context/ExceptionHandler.html

【讨论】:

【参考方案3】:

我在site faces中做了一个错误页面,并把错误的stacktrace 这段代码先放在web.xml中

<error-page>
                <error-code>500</error-code>
                <location>/errorpage.jsf</location>
</error-page>

虽然 jsf 页面有这段代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      >
<h:head>
    <h:outputStylesheet name="EstilosOV.css" library="css" />
    <!-- <h:outputScript name="sincontext.js" library="scripts"/> -->

</h:head>
<h:body >
<table  border="0" align="center" bordercolor="#FFFFFF">

    <tr bgcolor="#1D2F68">
      <td colspan="4"  class="TablaHeader2"> PLAN SEGURO</td>
    </tr>
    <tr  bgcolor="#FDF2AA">
    <td colspan="4"  class="HeaderExcepcion">
      <h:graphicImage library="images" name="errormark.jpg"/>
      <font size="5px" color="#CC0000" >Error de ejecución</font>
      </td>
    </tr>
    <tr >
    <td colspan="3" class="anuncioWarning2">Ocurrio un error al realizar la operación, favor de intentarlo nuevamente, si el error aún se presenta, favor de notificarlo a soporte técnico al 5147-31-00 extensión 6893</td>
    </tr>
    <tr>
      <td  colspan="3" class="TablaHeader2"></td>
    </tr>

</table>
    <h:form id="formerror">
        <h:inputHidden id="valuestack" value="#errorDisplay.stackTrace"></h:inputHidden>
    </h:form>
</h:body>

</html>

请注意,motif 可以让您调试堆栈跟踪,以了解隐藏字段中的异常。 看看类是怎么定义的恢复StackTrace

public class ErrorDisplay implements Serializable

    private static final long serialVersionUID = 6032693999191928654L;
    public static Logger LOG=Logger.getLogger(ErrorDisplay.class);

    public String getContacto() 
        return "";
    

    public String getStackTrace() 
        FacesContext context = FacesContext.getCurrentInstance();
        Map requestMap = context.getExternalContext().getRequestMap();
        Throwable ex = (Throwable) requestMap.get("javax.servlet.error.exception");

        StringWriter writer = new StringWriter();
        PrintWriter pw = new PrintWriter(writer);
        fillStackTrace(ex, pw);
        LOG.fatal(writer.toString());

        return writer.toString();
    

    private void fillStackTrace(Throwable ex, PrintWriter pw) 
        if (null == ex) 
            return;
        

        ex.printStackTrace(pw);

        if (ex instanceof ServletException) 
            Throwable cause = ((ServletException) ex).getRootCause();

            if (null != cause) 
                pw.println("Root Cause:");
                fillStackTrace(cause, pw);
            
         else 
            Throwable cause = ex.getCause();

            if (null != cause) 
                pw.println("Cause:");
                fillStackTrace(cause, pw);
            
        
    

并且当你在文件 facesconfig 中完成这个 bean 定义时已经附加

<managed-bean>
            <description>
                Bean que sirve para llenar la especificacion de un error. Stacktrace 
            </description>
            <managed-bean-name>errorDisplay</managed-bean-name>
            <managed-bean-class>mx.com.tdc.datos.page.bean.ErrorDisplay</managed-bean-class>
            <managed-bean-scope>session</managed-bean-scope>
        </managed-bean>

我希望这会有所帮助

【讨论】:

【参考方案4】:

在 JSF 中向用户显示错误消息的一般方法是使用 FacesMessage:

在 Java 方面:

...
if (errorOccurred) 
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("An error occurred blabla..."));

在 JSF(JSP 或 XHTML)页面中,只需在页面中使用 &lt;h:messages/&gt; 组件即可显示错误。

【讨论】:

【参考方案5】:

你可以放

<%@ page errorPage="error.jsp" %>

在 jour jsp/jsf 页面中。在 error.jsp 中,jou 会有:

<%@ page isErrorPage="true" %>

isErrorPage="true" 将为您的页面提供另一个隐式对象:异常(与您在 jsp 页面上已经有请求和响应的方式相同)。然后您可以从异常中提取消息。

Additional details

【讨论】:

【参考方案6】:

我遇到了同样的问题,并找到了描述如何在 JSF2 中使用 ExceptionHandler 的链接:

http://jugojava.blogspot.com/2010/09/jsf-2-exception-handling.html

【讨论】:

以上是关于JSF 1.x 通用异常处理的主要内容,如果未能解决你的问题,请参考以下文章

JSF ajax 请求中的异常处理

JSF 2全局异常处理,导航到错误页面没有发生

处理 AJAXified 组件的 JSF 2.0 异常的正确方法是啥?

jsf中的异常处理 - 在新页面中打印错误消息

通用异常处理程序可防止处理特定异常

Informix 存储过程通用异常处理