【问题标题】:Using @ExceptionHandler or some other annotation that would work like a Spring 4.1 AsyncUncaughtExceptionHandler使用 @ExceptionHandler 或其他类似 Spring 4.1 AsyncUncaughtExceptionHandler 的注释
【发布时间】:2014-06-21 05:24:24
【问题描述】:

我想配置和使用 Spring 4.1 AsyncUncaughtExceptionHandler。根据 Spring 团队 (see relevant comment here) 的说法,可以通过 <task:annotation-driven> 或通过实现 AsyncConfigurer 来配置 AsyncUncaughtExceptionHandler,如下所示:

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
 return new SimpleAsyncUncaughtExceptionHandler() ;
}

现在我的问题如下:是否有另一个类似于@ExceptionHandler 的网络层注释可以像AsyncUncaughtExceptionHandler 一样工作?

【问题讨论】:

    标签: spring spring-mvc


    【解决方案1】:

    正如评论中所述,这是我采取的一种方法:

    这是关于异步数据导入,因此所有类都称为 Import...

    我(还)没有做的是未捕获的异常处理,但是阅读你的帖子让我想到了它,它应该是 Spring-AOP 包装 Importer.process()方法。这不是全局解决方案,但可以通过使用更通用的 Result 对象来适应完整的应用程序。

    控制器使用 ImportRequests 来获取处理(或完成)消息。 Importer 本身不会从地图中删除结果,而是将其委托给控制器(用户正在单击删除)。我们还有一个 @Scheduled 任务,它会在 1 小时后清理完成的结果,以确保没有剩余。

    下面是控制器在处理过程中能够得到导入结果的部分代码:

    @Service
    public class ImportRequests {
        private final Map<User, ImportResult> importRequests = new ConcurrentHashMap<>();
    
        /** Add, remove, get methods for current user omitted */
    }
    

    public class ImportResult {
        /** The done. */
        private Future<Boolean> done;
        /** The error messages. */
        private List<String> messages = Collections.synchronizedList(new ArrayList<String>());;
    
    }
    

    @Service
    public class ImportService {
        @Autowired
        private ImportRequests importRequests;
    
        @Autowired
        private Importer importer;
    
        public ImportResult doImport(final ImportForm importForm) {
            ImportResult result = new ImportResult();
            importRequests.addImportResultForCurrentUser(result);
    
            /* This is the actual Async call (process) */
            result.setDone(importer.process(result));
            return result;
        }
    
    }
    

    @Service
    public class ImporterImpl implements Importer {
        /**
         * doProcess will import the *big* file and update the result object with the necessary messages
         */
        @Async
        public Future<Boolean> process(ImportResult result) {
            Boolean done = doProcess(result);
            return new AsyncResult<Boolean>(done);
        }
    }
    

    希望这会有所帮助。


    原文:

    我使用的一种可能性是 servletcontext 扫描的类上的“@ControllerAdvice”。

    您只需创建一个将异常作为参数的方法,并使用“@ExceptionHandler”注释该方法。您甚至可以为特定的异常类型设置多个处理程序。

    这些方法的结果再次由 DispatcherServlet 处理,因此您可以像使用请求映射一样呈现视图。

    【讨论】:

    • 谢谢马丁。问题是由另一个线程而不是 servlet 线程抛出的异常(就像这里的 Async 方法一样)不会被 @ExceptionHandler 捕获。
    • 那是真的......你想做什么?带有用户反馈的异步调用(即使引发异常)?
    • 嗯,好的。我做过类似的事情。我没有代码,但我会在星期一检查。它涉及让一个单例服务为每个用户保存一张期货地图。只有我没记错的情况下,未来才会基于布尔值,并保留长期运行过程的消息。也许你可以从那开始,否则在星期一;)
    猜你喜欢
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2021-03-24
    • 1970-01-01
    • 2014-06-13
    • 2018-07-21
    相关资源
    最近更新 更多