指定packageName或assignableTypes时未应用Spring@ControllerAdvice



演示该问题的示例项目位于:https://github.com/dirkbolte/javaexceptionhandlertest

我有一个控制器,它被声明为生成JSON内容:

@RestController
public class TestController {
@GetMapping(value = "exception", produces = MediaType.APPLICATION_JSON_VALUE)
public void test() {
}
}

相应的控制器建议应将任何异常映射到BAD_REQUEST:

@RestControllerAdvice
public class MyExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = Exception.class)
public void exceptionhandler() {
}
}

我测试了带有错误accept标头的调用是否会产生正确的错误响应代码(因为procudes指定了不同的内容(:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
class TestControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.get("/exception")
.accept(MediaType.APPLICATION_PDF)
).andExpect(status().isBadRequest());
}
}

上面的代码"失败成功":-(。在我的生产代码中,我想将控制器建议限制为某个控制器(或者某个包(,因此我在@ControllerAdvice:@RestControllerAdvice(assignableTypes = TestController.class)上指定了assignableTypes。现在测试失败了,因为不再调用异常处理程序。指定basePackagesbasePackageClasses或使用接口时也会发生同样的情况。

GitHub上的版本显示测试失败,所以我希望它很容易复制。

如何为一个或多个控制器显式使用ControllerAdvice?

此处请求的URL不会映射到任何Controller方法。这将导致状态406错误(由于指定的接受类型(。由于Controller方法没有抛出异常,因此不会调用ControllerAdvice。

在调度器级别,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#getExceptionHandlerMethod将用handlerMethod = null调用,这就是为什么只应用一般控制器建议的原因。

如果请求包含为控制器方法配置的附加元数据和/或从该方法中抛出异常,则ControllerAdvice将在此处工作。

最新更新