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 指点我!
我知道这通常是反过来发生的问题,所以我在这里有点警惕 :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 指点我!