【问题标题】:Usage of AsyncListener#onErrorAsyncListener#onError 的使用
【发布时间】:2014-02-18 16:25:05
【问题描述】:

我不明白何时调用 AsyncListener#onError 方法。 Javadoc 没有帮助:

通知此 AsyncListener 异步操作未能完成。

它怎么会失败?如何重现此错误?

更新:

// in HttpServlet doGet method
AsyncContext asyncContext = req.startAsync();
asyncContext.addListener(new AsyncListener() {
    // some code
    @Override
    public void onError(AsyncEvent event) {
        // when is it called?
    }
});
executeInSomeOtherThread(asyncContext);

我需要在其他线程中做什么才能使此异步操作失败?

【问题讨论】:

  • 为什么您觉得 Javadoc 不清楚?您希望它回答什么具体问题?
  • 正如我之前写的,我想了解异步操作是如何失败的。
  • 我添加了一些代码示例:)

标签: java asynchronous servlet-3.0


【解决方案1】:

如果在执行异步操作时抛出异常,将调用onError。

它们通常是扩展 java.io.IOException 的 Throwable,由不可靠的连接导致的 I/O 失败或由于客户端和服务器不匹配导致的逻辑错误导致的协议级别异常。

调用 onError 时可以获取 Throwable:

event.getThrowable();

编辑以解决 mjaggard 的后续问题

暂时忘记 AsyncContext,考虑以下类:

public class MyRunnableClass implements Runnable {
    private Listener mListener;

    interface Listener {
        void onError(Throwable error);
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    @Override
    public void run() {
        // Some important code to be executed goes here

        // Pretend an exception was caught in a try/catch/finally
        // block that was doing an I/O operation

        Throwable someError = new IOException();

        if (mListener != null) {
            mListener.onError(someError);
        }
    }
}

现在是否更清楚了如何调用侦听器的 onError 方法,因为调用 MyRunnableClass 的 run 方法时引发了异常?

MyRunnableClass mrc = new MyRunnableClass();
mrc.setListener(new Listener() {
    @Override
    public void onError(Throwable error) {

    }
});

Executors.newSingleThreadScheduledExecutor().schedule(mrc, 1000L, TimeUnit.MILLISECONDS);

这与 AsyncContext 保持侦听器并在遇到希望报告给侦听器的异常时通知它的方式没有什么不同。 run 方法的调用方式实际上是次要的,因为正在执行的代码的所有者也是持有对侦听器的引用的人。

【讨论】:

  • 你能用代码示例展示一下吗?据我了解,您在另一个线程中的执行是按照您的意愿完成的,但通常使用执行器。那不知道 AsyncContext 那么异常如何到达那里?
  • 与 Thread 类的 run() 方法一样,我们不能允许在 throws 类中声明异常或允许未捕获的异常,因为我们实际上并没有调用 run 方法,它是 java 线程系统管理它。因此,要添加 Michael 上面所说的内容,java 线程系统必须在调用时捕获这些异常并将其传递给 onError()。
  • 但 Java 线程系统无法访问 AsyncListener 或任何将线程链接到侦听器的方式。
  • 该死,愚蠢的 stackoverflow 将我的积分奖励给了我认为错误的答案:-(
  • @mjaggard 请查看我编辑的答案,希望能解决您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 2014-04-12
  • 1970-01-01
相关资源
最近更新 更多