Spring @ControllerAdvice/@ExceptionHandler 不起作用

Posted

技术标签:

【中文标题】Spring @ControllerAdvice/@ExceptionHandler 不起作用【英文标题】:Spring @ControllerAdvice/ @ExceptionHandler not working 【发布时间】:2021-05-22 09:36:45 【问题描述】:

我的 Spring Boot 服务将完成一项工作并在成功后以 0 退出(没有 restcontroller),但我希望它在每个异常时也退出,所以我在一个类上添加了 @ControllerAdvice 并放置了这个方法:

@ControllerAdvice
@RequiredArgsConstructor
@Slf4j
public class ImportInekData 

final InekService inekService;

final ImportDataService dataService;

public void doTheJob()
    log.info("Fetching new list from Inek.");
    UpdatedList updatedList = inekService.getUpdatedList();
    List<Standort> toBeUpdated = updatedList.getToBeUpdated();
    List<String> toBeDeleted = updatedList.getToBeDeleted();
    log.info("List fetched with " + toBeUpdated.size() + " valid entries to be updated and " + toBeDeleted.size() + " entries marked for deletion. ");
    log.info("Pushing to DB...");
    dataService.importAll(toBeUpdated);


@EventListener
public void onStart(ContextStartedEvent start)
    log.info("Application started.");
    doTheJob();
    log.info("Import finished.");
    SpringApplication.exit(start.getApplicationContext(), () -> 0);


@ExceptionHandler(value = Exception.class)
public String outOnException(Exception e)
    log.error("Exception occurred see logs. Stopping..");
    SpringApplication.exit(context, () -> -1);
    return "dying";



一切正常,但是当我抛出 IllegalArgumentException 时,不会调用 @ExceptionHandler 方法。首先我有一个没有参数的 void 方法,然后我开始尝试使用 String 返回和至少一个参数 - 这不是必需的。

如何使它工作?有没有更好的方法让我的案例对每个异常做出反应?

【问题讨论】:

全班分享。 @ControllerAdvice 仅适用于控制器。你真的从你的控制器中抛出异常吗?你说你有工作,所以可能不正确? 已更新,添加完整类在使用中 【参考方案1】:

Spring 中的Controller Advices 是一种旨在在spring MVC 级别正确处理异常的机制。

简而言之,Spring MVC 是一个 Web 框架,因此,它假定您有某种由最终用户或前端调用的 Web 端点。此端点是后端代码的“入口点”,可以拥有服务、查询数据库等。如果在此后端流程中通常抛出异常,您不希望 Web 端点返回 500 内部服务器错误,因此 Spring 提供了方便映射这些异常的工具:将它们转换为带有“好看”消息的 json ,使用正确的 HTTP 代码,等等。

如果您没有任何控制器,那么控制器建议的整个概念不适用于您的流程,因此使用它没有意义......

现在真正的问题是,您希望通过这种异常处理实现什么目标? 如果应用程序上下文通常无法启动,spring boot 应用程序将正常关闭...

如果您想以编程方式关闭应用程序,请确保您已阅读 this thread

【讨论】:

我读了这个线程——我想在每个异常上以编程方式关闭应用程序——“在每个异常上”似乎是困难的部分? (如果工作成功完成,我已经结束了申请)- - 这是我在问题的第一句话中写的?! 看,控制器建议意味着 Spring MVC MVC 意味着一个始终获取连接并服务请求的线程池。但是您不需要这种行为,您也根本不需要网络服务器(tomcat/jetty/whatever)。所以这是一种“一次性执行”的代码。在这种情况下,请阅读命令行运行程序:***.com/questions/58166325/… 如果流程的某些部分引发异常 - 它将传播到入口点(应该只有一个入口点),这一切都归结为简单的 try catch .

以上是关于Spring @ControllerAdvice/@ExceptionHandler 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot @ControllerAdvice 拦截异常并统一处理

spring boot中@ControllerAdvice的用法

[spring-boot] ControllerAdvice异常类

Spring boot异常统一处理方法:@ControllerAdvice注解的使用

Spring Boot @ControllerAdvice 部分工作,不适用于自定义异常

Spring Boot @ControllerAdvice 异常处理程序未触发