【问题标题】:Adding Global Error Handling for Spring Rest Controllers为 Spring Rest 控制器添加全局错误处理
【发布时间】:2018-09-12 20:25:08
【问题描述】:

我有很多这样的控制器

@RestController
@RequestMapping("/contracts")
public class ContractsController {

    @Autowired
    ContractsService service;

    @PostMapping("/selectAll")
    public WebMessageModel selectAll(@RequestBody ContractFiltersInputModel inputModel) {
        return new WebMessageModel(true, service.selectAll(inputModel));
    }
}

我还有另一个控制器

@Controller
public class BaseController {

    private static Logger logger = LoggerFactory.getLogger(IndexController.class);

    @RequestMapping
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {

            String requestURI = request.getRequestURI();
            StringBuffer requestURL = request.getRequestURL();
            logger.info("-----requestURI => " + requestURI + ", requestURL => " + requestURL);

            request.getRequestDispatcher(requestURI).forward(request, response);

            logger.info("-----response has been commited");

        } catch (Throwable t) {
            t.printStackTrace();
            request.getRequestDispatcher("/handleException").forward(request, response);

        }

    }
}

我需要所有传入的请求都通过这个 BaseController 才能创建一个全局 TRY-CATCH 块。我该如何实施?这种方法真的是个好主意吗?也许还有其他一些很棒的方法?

【问题讨论】:

  • 如果你想处理异常考虑使用@ControllerAdvice

标签: spring spring-mvc controller


【解决方案1】:

如果您想在进入控制器方法之前拦截对控制器端点的每个请求,您需要实现filter。您可以通过tutorial 了解如何实现过滤器。

如果您想在一个地方捕获因对控制器端点的请求而导致的所有异常(异常可能在任何地方抛出 - 控制器、服务、存储库等),那么您应该在一个位置实现 ExceptionHandlers ControllerAdvice。一个简单的例子是这样的:

@ControllerAdvice
public class ExceptionHandlerAdvice {

@ExceptionHandler(MismatchedInputException.class)
public ResponseEntity<Void> handleMismatchedInputException(MismatchedInputException e) {
    return ResponseEntity.status(BAD_REQUEST).build();
}

@ExceptionHandler(InvalidFormatException.class)
public ResponseEntity<Void> handleInvalidFormatException(InvalidFormatException e) {
    return ResponseEntity.status(UNPROCESSABLE_ENTITY).build();
}

}

以上将确保在异常处理程序中指定的任何异常都将在此处捕获,以便可以简化来自 REST API 的异常响应。更多关于同一here

【讨论】:

    【解决方案2】:

    您可以use filters 在请求之前或之后执行一些逻辑。在您的情况下,全局错误处理会更有帮助:

    @ControllerAdvice
    public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    
        @ExceptionHandler(value = { IllegalArgumentException.class, IllegalStateException.class })
        protected ResponseEntity<Object> handleConflict(
          RuntimeException ex, WebRequest request) {
            String bodyOfResponse = "This should be application specific";
            return handleExceptionInternal(ex, bodyOfResponse, 
              new HttpHeaders(), HttpStatus.CONFLICT, request);
        }
    }
    

    这个sn-p取自here

    【讨论】:

      【解决方案3】:

      你要找的是@ControllerAdvice。这里是如何使用它http://blog.codeleak.pl/2013/11/controlleradvice-improvements-in-spring.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-24
        • 2020-01-18
        • 1970-01-01
        • 1970-01-01
        • 2017-07-02
        相关资源
        最近更新 更多