Spring Boot不会使用@ControllerAdvice覆盖异常
我想从控制器建议方面引发一个标准的自定义异常,但是由于某种原因,我的自定义异常没有被Spring Boot(1.3.3-RELEASE)捕获。
这是我的代码:
我的测试
@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(MyApplication.class)
@WebIntegrationTest("server.port:9000") 
public class ControllerTest {
    private final String URL = "http://localhost:9000";
    @Test
    public void testCustomExceptionResponse() {
        // Invoke my controller generating some exception
        Map error = restTemplate.getForObject(URL+"/exception/", Map.class);
        assertTrue(error.get("exception").contains("MyCustomException"));
    }
}
控制器
@RequestMapping(value = "/", method = RequestMethod.GET)public List<Object> findAll() throws Exception {
    // generate whatever exception here
    if (1<2) throw new IllegalIdentifierException("test whatever exception");
    return ccRepository.findByActive(true);
}
用@ControllerAdvice注释的GlobalExceptionHandler
@ControllerAdvicepublic class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    // Catch whatever exception to throw my custom exception
    @ExceptionHandler(Exception.class)
    public void handleException(Exception ex) throws Exception {
        logger.error("Exception Occured: ", ex);
        throw new MyCustomException(ex.getLocalizedMessage());
    }
}
我已经调试了代码并且执行了handleException方法,但是奇怪的是正在抛出MyCustomException,但是控制器响应返回了抛出的原始异常:
{timestamp=1473963128439, status=500, error=Internal Server Error, exception=org.hibernate.metamodel.relational.IllegalIdentifierException, message=test whatever exception, path=/exception/}我期望有这样的东西:
exception=com.myapp.MyCustomException据我所知,控制器建议是捕获控制器中所有异常以绑定某种逻辑(在我的情况下是记录程序)的通用方法,然后我通过使用自定义异常来自定义意外异常。
我是否缺少有关Spring Boot如何处理异常的信息?
回答:
这并不是ControllerAdvice的确切目的。
回答:
- 你抛出IllegalIdentifierException
 - 您在ControllerAdvice中捕获了它
 - 因为您抛出MyCustomException,所以您的handleException没有完成
 - 这会在DispatcherServlet中引发一个异常,而您的原始异常(IllegalIdentifierException)是根本原因。
 
回答:
Controller Advice旨在在出现错误的情况下返回有效的Http响应。
例如,您可以将其更改为:
@ControllerAdvicepublic class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) throws Exception {
        System.out.println("Exception Occured: " + ex);
        return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Exception: " + ex.getLocalizedMessage());
    }
}
从而:
- ControllerAdvice的方法将成功完成(返回响应);
 - DispatcherServlet会很高兴您的。
 - 原始异常不会成为新错误的根本原因,现在可以成功吞咽
 - 客户端收到带有HTTP错误代码(我选择HttpStatus.INTERNAL_SERVER_ERROR)的消息“异常:测试任何异常”。
 
您可以使用以下命令进行测试MockMvc:
@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(Launcher.class)
@WebAppConfiguration
public class ControllerTest {
    @Autowired
    private WebApplicationContext webApplicationContext;
    @Test
    public void testCustomExceptionResponse() throws Exception {
        MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        mockMvc.perform(MockMvcRequestBuilders.get("/your/uri"))
        .andExpect(MockMvcResultMatchers.status().isInternalServerError())
        .andExpect(MockMvcResultMatchers.content().string("Exception: test whatever exception"));
        assertTrue(true);
    }
}
以上是 Spring Boot不会使用@ControllerAdvice覆盖异常 的全部内容, 来源链接: utcz.com/qa/416013.html

