其他分享
首页 > 其他分享> > spring – @ControllerAdvice覆盖异常@ResponseStatus

spring – @ControllerAdvice覆盖异常@ResponseStatus

作者:互联网

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

例外:

@ResponseStatus(HttpStatus.BAD_REQUEST)
public class GreetException extends 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.

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

解决方法:

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

Spring article about exception handling in Spring MVC看到这个引用:

When an annotated exception is thrown from a controller method, and not handled elsewhere, it will automatically cause the appropriate HTTP response to be returned with the specified status-code.

尽管具有带有通用处理程序的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
    }
  }
}

标签:spring,spring-boot,spring-mvc,spring-annotations
来源: https://codeday.me/bug/20190824/1703820.html