将 Struts 2 异常处理程序映射到操作

发布于 2024-11-02 21:23:25 字数 1558 浏览 0 评论 0原文

我将 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";
}

当我运行我的程序时,异常处理程序总是获得空异常。我正在使用链类型重定向到异常处理程序。我需要实现某种 ExceptionAware 接口吗? Struts 2 异常设置器除了 setException 之外还有其他名称吗?

注意:在编写此程序时,我试图遵循本教程

I have Struts 2 configured to redirect any java.lang.Exception to a special Action which logs the exception. My redirection works, but my Action always gets a null exception (even when I explicitly throw an Exception). Here is my struts.xml file:

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

In my error processor, I have the following:

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

In the throwsException class, I have the following:

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

When I run my program, the Exception handler always gets a null exception. I am using the chain type to redirect to the exception handler. Do I need to implement some sort of ExceptionAware interface? Is the Struts 2 exception setter called something besides setException?

Note: I was trying to follow this tutorial when writing this program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离不开的别离 2024-11-09 21:23:25

使用 struts2 版本 2.3.1.2 我在错误处理程序中没有收到空异常,一切都按广告进行。确保您使用的是未经修改的默认堆栈。

至于可靠的来源,我们可以参考 ExceptionMappingInterceptor 的拦截器文档和 链接拦截器。 ExceptionMappingInterceptor 将 ExceptionHolder 推送到值堆栈上,从而公开异常属性。链接拦截器将值堆栈上的所有属性复制到目标。由于 ExceptionHolder 位于堆栈上,如果有 Exception 的 setter,它将被设置。

以下是生成工作示例的所有文件:

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

Bomb (仅抛出 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!");
    }
}

View foromb (/WEB-INF/content/bomb.jsp) [< strong>永远无法访问]

<%@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!

Using struts2 version 2.3.1.2 I do not get a null exception in my error handler everything works as advertised. Ensure you are using an unmodified defaultStack.

As far as credible sources, we can reference the interceptor documentation for ExceptionMappingInterceptor and Chaining Interceptor. The ExceptionMappingInterceptor pushes an ExceptionHolder onto the value stack which in turn exposes an exception property. The chaining interceptor copies all the properties on the value stack to the target. Since ExceptionHolder is on the stack if there is a setter for Exception it will be set.

Here are all the files which produce a working example:

struts.xml (kept quite similar to the questions):

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

Bomb (just throws 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!");
    }
}

View for bomb (/WEB-INF/content/bomb.jsp) [Never reachable]

<%@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>

View for 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>

Output:

I see error.jsp render and I see the following printed on the glassfish console:

INFO: Is exception null: false
INFO: Hello from Exception!
罪歌 2024-11-09 21:23:25

我也遇到了和你一样的问题!

虽然由 Struts 填充 exception 字段要干净得多,但似乎该字段填充并未发生(如您所述)。为了解决这个问题,我从异常处理程序类(您的 myErrorProcessor 类)中删除了异常字段(及其 getter/setter),并将其替换为“手动”从 < code>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 对象中找到)。

让我知道这对您有何作用! :)

I was having the same issue you were having!

While it is much cleaner to have the exception field populated by Struts, it appears that this field population is not happening (as you stated). To get around this, I removed the exception field (and its getter/setter) from my Exception handler class (your myErrorProcessor class) and replaced that with a method to "manually" extract the exception from the 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;
}

I can then use instanceof to make sure the exception Object is the type that I was expecting and then handle that exception accordingly (like writing messages found in a custom Exception object to a database).

Let me know how this works for you! :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文