2011-04-21 9 views
11

Tengo Struts 2 configurado para redirigir cualquier java.lang.Exception a una acción especial que registra la excepción. Mi redirección funciona, pero mi acción siempre obtiene una excepción nula (incluso cuando expulso explícitamente una excepción). Aquí está mi archivo struts.xml:Mapeo Struts 2 Exception Handler para una Acción

<global-results> 
    <result name="errHandler" type="chain"> 
    <param name="actionName">errorProcessor</param> 
    </result> 
</global-results> 

<global-exception-mappings> 
    <exception-mapping exception="java.lang.Exception" result="errHandler" /> 
</global-exception-mappings> 

<action name="errorProcessor" class="myErrorProcessor"> 
     <result name="error">/error.jsp</result> 
</action> 

<action name="throwExceptions" class="throwExceptions"> 
     <result name="success">done.jsp</result> 
</action> 

En mi procesador de error, tengo el siguiente:

public class myErrorProcessor extends ActionSupport { 

    private Exception exception; 

    public String execute() { 
     System.out.println("null check: " + (exception == null)); 
     return "error"; 
    } 

    public void setException(Exception exception) { 
     this.exception = exception; 
    } 

    public Exception getException() { 
     return exception; 
    } 
} 

En la clase throwsException, Tengo el siguiente:

public String execute() { 
    int x = 7/0; 
    return "success"; 
} 

Cuando Ejecuto mi programa, el controlador de excepciones siempre obtiene una excepción nula. Estoy usando el tipo de cadena para redirigir al manejador de excepciones. ¿Debo implementar algún tipo de interfaz ExceptionAware? ¿El setter de excepciones de Struts 2 se llama algo además de setException?

Nota: Intenté seguir this tutorial al escribir este programa.

+0

He proporcionado un ejemplo que duplica el comportamiento del tutorial vinculado, sin embargo, incluye todos los archivos necesarios en su totalidad para reducir la posibilidad de error. – Quaternion

Respuesta

4

¡Estaba teniendo el mismo problema que estaba teniendo!

Si bien es mucho más limpio tener el campo exception poblado por Struts, parece que esta población de campo no está sucediendo (como usted indicó). Para evitar esto, me quita el campo excepción (y su captador/definidor) de mi clase de manejador de excepción (la clase myErrorProcessor) y repuestos que con un método para "manualmente" extraer la excepción de la ValueStack:

/** 
* Finds exception object on the value stack 
* 
* @return the exception object on the value stack 
*/ 
private Object findException() {   
    ActionContext ac = ActionContext.getContext(); 
    ValueStack vs = ac.getValueStack(); 
    Object exception = vs.findValue("exception");  

    return exception; 
} 

Puedo usar instanceof para asegurarme de que la excepción Object es del tipo que esperaba y luego manejar esa excepción en consecuencia (como escribir mensajes encontrados en un objeto personalizado Exception en una base de datos).

¡Avíseme cómo funciona esto para usted! :)

+0

Funciona perfectamente para mí. ¡Gracias! –

6

Uso de struts2 versión 2.3.1.2 No obtengo una excepción nula en mi controlador de errores, todo funciona como se anuncia. Asegúrese de que está utilizando una plataforma predeterminada no modificada.

En cuanto a las fuentes creíbles, podemos hacer referencia a la documentación del interceptor para ExceptionMappingInterceptor y Chaining Interceptor. El ExceptionMappingInterceptor inserta un ExceptionHolder en la pila de valores que a su vez expone una propiedad de excepción. El interceptor de encadenamiento copia todas las propiedades en la pila de valores al objetivo. Como ExceptionHolder está en la pila si hay un setter para Exception, se establecerá.

continuación se muestran todos los archivos que producen un ejemplo de trabajo:

struts.xml (mantuvo bastante similares a las preguntas):

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE struts PUBLIC 
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 
"http://struts.apache.org/dtds/struts-2.3.dtd"> 

<struts> 
    <constant name="struts.devMode" value="true" /> 
    <constant name="struts.ui.theme" value="simple" /> 
    <package name="kenmcwilliams" namespace="/" extends="struts-default"> 
     <global-results> 
      <result name="errHandler" type="chain"> 
       <param name="actionName">errorProcessor</param> 
      </result> 
     </global-results> 
     <global-exception-mappings> 
      <exception-mapping exception="java.lang.Exception" result="errHandler" /> 
     </global-exception-mappings> 
     <action name="errorProcessor" class="com.kenmcwilliams.test.myErrorProcessor"> 
      <result name="error">/WEB-INF/content/error.jsp</result> 
     </action> 
     <action name="throwExceptions" class="com.kenmcwilliams.kensocketchat.action.Bomb"> 
      <result name="success">/WEB-INF/content/bomb.jsp</result> 
     </action> 
    </package> 
</struts> 

MyErrorProcessor.java

package com.kenmcwilliams.test; 

import com.opensymphony.xwork2.ActionSupport; 

public class MyErrorProcessor extends ActionSupport { 

    private Exception exception; 

    @Override 
    public String execute() { 
     System.out.println("Is exception null: " + (exception == null)); 
     System.out.println("" 
       + exception.getMessage()); 
     return "error"; 
    } 

    public void setException(Exception exceptionHolder) { 
     this.exception = exceptionHolder; 
    } 

    public Exception getException() { 
     return exception; 
    } 
} 

bomba (simplemente arroja RuntimeException):

package com.kenmcwilliams.kensocketchat.action; 

import com.opensymphony.xwork2.ActionSupport; 

public class Bomb extends ActionSupport{ 
    @Override 
    public String execute() throws Exception{ 
     throw new RuntimeException("Hello from Exception!"); 
    } 
} 

Ver para bomb (/ WEB-INF/content/bomb.JSP) [Nunca alcanzable]

<%@taglib prefix="s" uri="/struts-tags"%> 
<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>The Bomb!</title> 
    </head> 
    <body> 
     <h1>The Bomb!</h1> 
    </body> 
</html> 

Ver para el error (/WEB-INF/content/error.jsp)

<%@taglib prefix="s" uri="/struts-tags"%> 
<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>Global Error Handler</title> 
    </head> 
    <body> 
     <h1>Global Error Handler</h1> 
     <s:property value="exception.stackTrace"/> 
    </body> 
</html> 

Salida:

veo error.jsp prestar y Veo lo siguiente impreso en la consola glassfish:

INFO: Is exception null: false 
INFO: Hello from Exception! 
+1

¡Gran explicación con código completo! Funciona de maravilla. Gracias ! – Saurabh

Cuestiones relacionadas