Отображение Struts 2 Обработчик исключений для действия
У меня есть Struts 2, настроенный на перенаправление любого java.lang.Exception на специальное действие, которое регистрирует исключение. Мое перенаправление работает, но мое действие всегда получает нулевое исключение (даже когда я явно бросаю исключение). Вот мой файл struts.xml:
<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>
В моем процессоре ошибок у меня есть следующее:
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;
}
}
В классе throwsException у меня есть следующее:
public String execute() {
int x = 7 / 0;
return "success";
}
Когда я запускаю свою программу, обработчик Exception всегда получает нулевое исключение. Я использую тип цепочки для перенаправления на обработчик исключений. Нужно ли мне реализовать какой-то интерфейс ExceptionAware? Является ли установщик исключения Struts 2 чем-то помимо setException?
Примечание. Я пытаюсь выполнить этот учебник при написании этой программы.
Ответы
Ответ 1
У меня была та же проблема, что и у вас!
В то время как гораздо чище иметь поле exception
, заполненное Struts, кажется, что это полевое население не происходит (как вы сказали). Чтобы обойти это, я удалил поле исключения (и его getter/setter) из моего класса обработчика исключений (ваш класс myErrorProcessor
) и заменил его методом "вручную" извлечь исключение из 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;
}
Затем я могу использовать instanceof
, чтобы исключение Object
- это тип, который я ожидал, и затем обрабатываю это исключение (например, записывая сообщения, найденные в пользовательском exception
объекте в базу данных).
Сообщите мне, как это работает для вас!:)
Ответ 2
Использование struts2 версии 2.3.1.2 Я не получаю исключение null в моем обработчике ошибок, все работает так, как рекламируется. Убедитесь, что вы используете немодифицированный defaultStack.
В отношении достоверных источников мы можем ссылаться на документацию перехватчика для ExceptionMappingInterceptor и Цепочки-перехватчики, ExceptionMappingInterceptor толкает ExceptionHolder в стек значений, который, в свою очередь, предоставляет свойство исключения. Цепочный перехватчик копирует все свойства в стек значений к цели. Поскольку ExceptionHolder находится в стеке, если есть установленный для Exception параметр, он будет установлен.
Вот все файлы, которые создают рабочий пример:
struts.xml(очень похож на вопросы):
<?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;
}
}
Бомба (просто бросает 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!");
}
}
Вид для бомбы (/WEB-INF/content/bomb.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>The Bomb!</title>
</head>
<body>
<h1>The Bomb!</h1>
</body>
</html>
Просмотр для ошибки (/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>
Вывод:
Я вижу рендеринг error.jsp, и на панели Glassfish я вижу следующее:
INFO: Is exception null: false
INFO: Hello from Exception!