返回 http code


在使用 spring boot 开发 rest 接口的时候,如果在 controller 中出现了未处理的异常,默认会返回500 错误。如果我们希望在某些条件下返回一个特定的 HTTP CODE(如404),可以这么做。

@RequestMapping("/student/{name}")
public ResponseEntity<?> getStudent(@PathVariable(name = "name") String studentName) {
    StudentEntity student = studentRepository.findByStudentName(studentName);
    if (student != null) {
        return new ResponseEntity<>(student, HttpStatus.OK);
    } else {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}

返回一个 ResponseEntity<?> 类型的值,正常情况下直接返回一个对象,否则,可以返回一个特定的 http code。也可以同时返回 code 和 body。

这种情况可以动态返回 HTTP Code,但对 Swagger 不友好,在 Swagger-UI 上看不出来你要返回的数据格式。

错误处理


有时候,我们可能忘记了做错误处理,controller 中出现了我们没有想到的异常。spring boot对异常处理提供了很多支持,但我比较常用的是两种方式,分别是 controller 级别错误处理的和全局的错误处理。

controller 级别的错误处理

public class FooController{

    //...
    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public void handleException() {
        //
    }
}

这种方式是在一个 controller 内部使用 @ExceptionHandler 标注一个方法,指定该方法来处理当前controller 内所有未处理的异常。

全局级别的错误处理

以下代码使用了 @ControllerAdvice 注解,并使用了多个 @ExceptionHandler 注解。他们的处理流程就像 try–catch一样,异常类型一样时,优先进入对应的catch块中,没有定义对应的catch块的话,则进入 Exception 的 catch 块中。

@ControllerAdvice
public class GlobalExceptionHandler {

    Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = IllegalArgumentException.class)
    @ResponseBody
    public ResponseEntity<String> parameterErrorHandler(HttpServletRequest req, IllegalArgumentException e) {
        return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public void othersErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        String url = req.getRequestURI();
        logger.error("request error at " + url, e);
    }

}

上面的处理逻辑如下: controller 中未处理的 IllegalArgumentException 异常会由 parameterErrorHandler 方法处理,其他所有 controller 中未处理的异常都会交给othersErrorHandler方法处理。