【问题标题】:How to listen to all errors in a servlet's request scope?如何监听 servlet 请求范围内的所有错误?
【发布时间】:2017-09-17 10:30:28
【问题描述】:

我的网络服务有 3 个Servlets 实例化相同的请求范围对象,该对象存储有关当前请求的信息,例如 URL 路径、使用的资源以及在执行期间抛出的错误。目的是记录这些错误,并将它们作为客户端响应的一部分以 JSON 或 XML 形式发送。

我希望使用:

public class ErrorEngine implements Thread.UncaughtExceptionHandler

创建一个类来捕获所有错误(在类代码中使用/不尝试),然后将它们保存到日志文件以及稍后将转到客户端的数组中。我做到了:

public ErrorEngine() {
    super();
    Thread.setDefaultUncaughtExceptionHandler(this);
    System.out.println("Error Handler Engine Started.");
}

@Override
public void uncaughtException(Thread t, Throwable e) {
    System.out.println("Thread: "+t.getId()+"; Error: "+e.getMessage());        
}

并且 Error Handler Engine Started 消息出现在控制台上,但是当我在实例化的servlet 的 service() 方法中使用 除法进行测试时错误处理程序,我创建用于测试的消息没有显示,只有常规堆栈跟踪。

那么,如何正确监听 servlet 请求范围内的所有错误?

我想在他们自己的类和代码中处理它们中的每一个,但我想从同一个地方记录它们,而不必在每次尝试/捕获时从我的错误处理程序类中调用方法,甚至因为错误可能出现在我没有为它们处理代码的地方,但我必须在日志中看到它们。

【问题讨论】:

    标签: java multithreading servlets error-handling listener


    【解决方案1】:

    错误处理引擎已启动 消息出现在控制台上,但是当我用零除法进行测试时 在实例化错误的 servlet 的 service() 方法中 处理程序,我创建用于测试的消息没有显示,只有 常规堆栈跟踪。

    你需要在Servlet的线程上设置ExceptionHandler,而不是Error Handler的

    见下例

    package test;
    
    import java.lang.Thread.UncaughtExceptionHandler;
    
    public class ErrorHandler implements UncaughtExceptionHandler {
    
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("Exception occurred in thread "+t.getName());
            System.out.println("Exception is "+e.getClass()+" ---------------");        
            System.out.println("Exception is "+e.getMessage());     
        }
    
    }
    
    
    package test;
    
    public class ExceptionThrower {
    
        void test(){
            Thread.currentThread().setUncaughtExceptionHandler(new ErrorHandler());
            Object obj = null;
            System.out.println(obj.toString());
        }
    
        public static void main(String[] args) {
            new ExceptionThrower().test();
            System.out.println("After exception"); //this wont execute
        }
    }
    

    这是输出

    Exception occurred in thread main
    Exception is class java.lang.NullPointerException ---------------
    Exception is null
    

    【讨论】:

    • 我相信我是这样做的,或者我没有在 setUn 上使用 '.currentThread()'... 我会在星期一检查一下。提前致谢。
    • 我可以在之前(在过滤器链中)这样做吗?
    【解决方案2】:

    您可以使用final doGet() / final doPost() 创建一个MyBaseServlet,它们分别调用myDoGet() / myDoPost() 方法(包裹在try{}catch(Throwable t){uncaughtException(t)} 周围)。

    然后每个 servlet 都应该扩展 MyBaseServlet 并在需要时覆盖 myDoPost()/myDoGet()甚至uncaughtException()的默认实现;

    【讨论】:

    • 所以我们需要用户尝试,即使我们执行 setDefaultUncaughtException() !?
    • 我在 doGet 中实例化的带有 try/catch 的类中发生的错误怎么办?
    【解决方案3】:

    最好的方法是实现另一个可以将异常重定向到的 servlet。在该 servlet 中,您可以处理异常并记录它。但是,除非错误被抛出,否则外部类无法处理和记录它,您仍然必须在每个 servlet 中拥有日志基础设施,以便捕获和处理异常。

    这是您的 web.xml 的样子:

    <servlet>
            <servlet-name>ErrorHandler</servlet-name>
            <servlet-class>ErrorHandler</servlet-class>
    </servlet>
    <!-- servlet mappings -->
    <servlet-mapping>
            <servlet-name>ErrorHandler</servlet-name>
            <url-pattern>/ErrorHandler</url-pattern>
    </servlet-mapping>
    <error-page>
        <exception-type>java.lang.Throwable</exception-type >
        <location>/ErrorHandler</location>
    </error-page>
    

    这里是完整教程的链接:

    https://www.tutorialspoint.com/servlets/servlets-exception-handling.htm

    【讨论】:

    • 所以如果/ErrorHandler有错误,就会出现infine循环...
    • 有面向对象的方法吗?
    • 我需要错误数据保持在同一个请求范围内。当我将它发送到其他 /uri 时,我无法将错误信息作为请求的服务发送的数据子集发送给我的客户端。
    猜你喜欢
    • 1970-01-01
    • 2013-01-08
    • 2013-06-16
    • 1970-01-01
    • 2011-09-06
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多