首页 > 解决方案 > Spring @ControllerAdvice/@ExceptionHandler 不起作用

问题描述

我的 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 返回和至少一个参数 - 这不是必需的。

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

标签: springexception

解决方案


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

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

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

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

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


推荐阅读