Spring 启动 @ExceptionHandler 在开发服务器上工作但不在本地工作

Spring Boot @ExceptionHandler working on dev server but not locally

我知道这通常是反过来发生的问题,所以我在这里有点警惕 :D

我构建了一个用户管理后端,它提供 UI 数据。当这个架构部署在我们的开发服务器上时,一切都运行得很好。但是,一旦我尝试 运行 集成测试(我们使用 Maven cargo tomcat 进行测试)或者如果我在本地 tomcat 中使用 war 文件,根本不使用异常处理程序。 Spring 仅显示一个标准的 500 响应,并将异常转换为正文。

针对类似问题仔细阅读 SO 只会得到建议我应该使用 @EnableWebMVC,但这既不适用于我的后端试图完成的任务,也不会改变任何内容。

我应该如何寻找这个问题的解决方案?具体来说,我能否以某种方式观察我的 controlleradvice 是否被扫描,是否有可能不被扫描的原因?

编辑:这些是相关文件:

Spring配置:

@Configuration
@ComponentScan(basePackageClasses = {UserManagementSpringConfiguration.class})
@EnableWebSecurity
public class UserManagementSpringConfiguration {

@Configuration
public static class ResourceMappingConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/ui/*/usermanagement").setViewName("forward:/usermanagement-ui/index.html");
//            registry.addViewController("/ui/*/*/generator/").setViewName("forward:/generator-ui/index.html");
        registry.addViewController("/ui/*/usermanagement/*").setViewName("forward:/usermanagement-ui/index.html");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // cache setting, otherwise fonts are not loaded in IE over https
        CacheControl cacheControl = CacheControl.noCache().mustRevalidate();
        registry.addResourceHandler("/ui/**/*").addResourceLocations("/usermanagement-ui/")
                    .setCacheControl(cacheControl);
        }

    }

}

控制器建议:

@ControllerAdvice
public class CustomResponseEntityExceptionHandler {

    public static final Logger LOG = EISLoggerFactory.getLogger(CustomResponseEntityExceptionHandler.class);

    @PostConstruct
    public void postConstruct() {
        LOG.debug("CustomExceptionHandler loaded and ready for use");
    }

    @ExceptionHandler(PasswordMismatchException.class)
    public final ResponseEntity<ErrorDetails> handlePasswordChangeMismatch(
            PasswordMismatchException ex,
            WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(
                new Date(),
                ex.getMessage(),
                request.getDescription(false),
                MessageKeys.mismatchedPassword);
        return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
    }
}

事实证明,我们编写的模块之一以及我的项目包含的模块为 Throwable.class 定义了一个 ExceptionHandler。在我的机器上,此 ControllerAdvice 在我自己的 ControllerAdvice 之前注册,这导致 Spring 首先查看那里。由于 Throwable 符合要求,Spring 不再问任何问题,只使用该处理程序。

我的直接问题的解决方案是将 @Order(Ordered.HIGHEST_PRECEDENCE) 添加到我的 ControllerAdvice。由于我在其中定义的异常非常具体,因此不会造成任何问题。

我还没有找到解释为什么两个 ControllerAdvice 类 的注册顺序在我的机器和我们的开发服务器之间如此一致。如果我发现任何东西,将会更新。目前,我认为这个问题得到了回答。

这个 SO 问题对于解决这个特定问题至关重要。也许它可以帮助将来的某人 link 这里:Setting Precedence of Multiple @ControllerAdvice @ExceptionHandlers

感谢 ValentinCarnu 指点我!