@ExceptionHandler 用于自定义 ResponseEntityExceptionHandler 中的 Spring 异常未调用类型异常

Posted

技术标签:

【中文标题】@ExceptionHandler 用于自定义 ResponseEntityExceptionHandler 中的 Spring 异常未调用类型异常【英文标题】:@ExceptionHandler for type Exception not called for Spring exception in custom ResponseEntityExceptionHandler 【发布时间】:2017-03-29 20:08:25 【问题描述】:

在阅读了一些关于为 Spring 制作自定义异常处理程序的博客文章后,我编写了以下类:

@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler 
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseEntity<Object> exceptionHandler(Exception e) 
        HashMap<String, Object> msg = new HashMap<>(2);
        msg.put("error", HttpStatus.PRECONDITION_FAILED.value());
        msg.put("message", "Something went wrong");
        return new ResponseEntity<>(msg, HttpStatus.BAD_REQUEST);
    

目的是在 JSON 响应中发送 msg,而不是放弃 Spring 异常,无论出于何种原因引发的异常。

但是,这个类不起作用。

当我点击我的服务器 API 的无效端点时,我得到默认响应负载:


  "timestamp": 1449238700342,
  "status": 405,
  "error": "Method Not Allowed",
  "exception": "org.springframework.web.HttpRequestMethodNotSupportedException",
  "message": "Request method 'POST' not supported",
  "path": "/bad_enpoint"

我错过了什么?

谢谢。

【问题讨论】:

你能详细说明“不工作”吗?它不会被调用?可以,但失败了? 我用更多信息更新了这个问题。它没有被调用,我仍然返回 Spring 默认 JSON,Spring 期望被“暴露” 【参考方案1】:

不会调用您的处理程序,因为您想将 Exception 映射到您的自定义错误响应,但 Spring MVC 很可能已经为 Exception 类注册了一个异常处理程序。当然,它还有一个可以处理HttpRequestMethodNotSupportedException

无论如何,覆盖整个 Spring MVC 异常处理/映射并不是一个好主意。您应该只关心特定的例外 - 您定义的例外。

请阅读 this article 以更深入地了解 Spring MVC 异常处理。

【讨论】:

感谢您的文章,我对 Spring 拥有自己的处理程序感到满意。但是,我不喜欢 Spring 通过发送带有 "exception": "org.springframework.web.HttpRequestMethodNotSupportedException", 之类的响应的内容来提供太多关于应用程序内部的信息。 好的,这是一个有效的点。尝试使用 HIGHEST PRECEDENCE 集添加 @Order 注释。看到这个答案:***.com/questions/19498378/… 这个使用@Order的链接正是我所需要的。【参考方案2】:
    您无需扩展 ResponseEntityExceptionHandler 即可使其工作。 设置两个 HttpStatuse 确实是个坏主意。
    @ControllerAdvice
    public class RestExceptionHandler  
        @ExceptionHandler(value = Exception.class)
        @ResponseBody
        public ResponseEntity<String> exceptionHandler(Exception e) 
            return new ResponseEntity<>("Something went wrong", HttpStatus.BAD_REQUEST);
        
    

【讨论】:

我仍然得到相同的 JSON 响应(见问题底部)而不是 "Something went wrong" @ControllerAdvice 是控制器的方面。您的 AJAX 调用甚至没有到达控制器 - 从响应中我猜您没有在 /bad_enpoint 控制器上实现 POST(或根本没有控制器) 我有一个定义端点的@RestController 类。 @RestController 和 @ControllerAdvice 应该注解在同一个类上吗? 不,将@ControllerAdvice 类视为所有控制器的方面。你能粘贴你的@RestController 课程吗? 很遗憾我不能,它是一个专有应用程序。感谢您的帮助。

以上是关于@ExceptionHandler 用于自定义 ResponseEntityExceptionHandler 中的 Spring 异常未调用类型异常的主要内容,如果未能解决你的问题,请参考以下文章

WebApi v2 ExceptionHandler 不适用于 HttpPost

全局异常方式处理自定义异常 @RestControllerAdvice + @ExceptionHandler

@ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常

Spring Boot @ControllerAdvice 部分工作,不适用于自定义异常

ExceptionHandler 不处理异常

SpringBoot(十九)@ControllerAdvice+@ExceptionHandler全局捕获Controller异常