java – Spring引导不使用@ControllerAdvice重写Exception

我希望从控制器建议方面抛出一个标准的自定义异常但由于某种原因我的自定义异常没有被
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);
}

GlobalExceptionHandler使用@ControllerAdvice注释

@ControllerAdvice
public 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中捕获它
>您的handleException因为抛出MyCustomException而未完成
>这会在DispatcherServlet中引发异常,并将原始异常(IllegalIdentifierException)作为根本原因.

你应该做什么

Controller Advice用于在出现错误时返回有效的Http响应.

例如,您可以将其更改为:

@ControllerAdvice
public 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);
    }
}
点赞