【问题标题】:@ControllerAdvice overrides exception @ResponseStatus@ControllerAdvice 覆盖异常 @ResponseStatus
【发布时间】:2016-11-22 11:46:01
【问题描述】:

我不知道为什么,但 @ControllerAdvice 使用 @ResponseStatus 注释覆盖在 Exception 级别定义的响应代码。

例外:

@ResponseStatus(HttpStatus.BAD_REQUEST)
公共类 GreetException 扩展 RuntimeException {}

控制器:

@RestController
@RequestMapping("/")
public class GreetController {

    @RequestMapping(method = RequestMethod.GET)
    public String greet() {
        throw new GreetException();
    }
}

控制器建议:

@ControllerAdvice
public class ExceptionConfiguration {

    @ResponseStatus(HttpStatus.CONFLICT)
    @ExceptionHandler(RuntimeException.class)
    public void handleConflict() {}
}

当来自GreetController 的 greet 方法被调用时,响应为 409 - CONFLICT。因为我专门提供了异常级别的响应代码,所以我希望这将是返回的代码 (400 - BAD_REQUEST)。

当然,这是一个过于简化的示例,但我们使用 RuntimeException 定义定义了一个控制器通知,因此我们可以为每个未捕获的异常分配一个 id。

实现预期行为的正确方法是什么?

【问题讨论】:

  • 在你的 controllerAdvice 类中,你应该使用 GreetException 类作为 ExceptionHandler 而不是 RuntimeException 类。 @ExceptionHandler(GreetException.class) public void handleConflict() {}。抛出异常时要执行的最后一个类将是您的 controllerAdvice。
  • @duardito RuntimeException 的异常处理程序是捕获所有未捕获的内容。因为我声明了 GreetException 的响应状态,所以我不希望使用 RuntimeE 处理程序。

标签: spring spring-mvc spring-boot spring-annotations


【解决方案1】:

用@ResponseStatus 注释异常的问题是,这只会在异常未在其他地方处理时触发。

请参阅Spring article about exception handling in Spring MVC 的此引述:

当一个带注释的异常从控制器方法中抛出,并且没有在其他地方处理时,它会自动导致返回相应的 HTTP 响应,并带有指定的状态码。

同一篇文章描述了使它工作的方法,尽管有一个带有通用处理程序的ControllerAdvice。见Paragraph about ControllerAdvice。

如果用@ResponseStatus 注释,您基本上要做的就是在通用处理程序中重新抛出异常:

@ControllerAdvice
public class ExceptionConfiguration {

  @ResponseStatus(HttpStatus.CONFLICT)
  @ExceptionHandler(RuntimeException.class)
  public void handleConflict(RuntimeException e) throws RuntimeException {
    // Check for annotation
    if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
      // Rethrow Exception
      throw e;
    }
    else {
      // Provide your general exception handling here
    }
  }
}

【讨论】:

  • 这显然是正确的答案。我在发帖之前浏览了这篇文章。下次我会更加小心。
  • 在处理 ResponseStatusException 时,我必须删除 if 语句,因为它在字段中包含 ResponseStatus,而不是注释。之后它就像一个魅力!谢谢!
【解决方案2】:

你的 ControllerAdvice 不知道 GreetException,所以它是 抛出“HttpStatus.CONFLICT”而不是“HttpStatus.BAD_REQUEST”

请为您的参考找到以下 spring 文档:

https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

请更改ControllerAdvice代码如下:

@ControllerAdvice
public class ExceptionConfiguration {

    @ResponseStatus(HttpStatus.CONFLICT)
    @ExceptionHandler(RuntimeException.class)
    public void handleRuntimeException() {}

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(GreetException.class)
    public void handleGreetException() {}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-23
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2018-07-13
    相关资源
    最近更新 更多