Restlight支持业务自定义异常处理逻辑。对于Controller方法中抛出的异常,处理逻辑和顺序如下(注意:一个异常只会被处理一次):

1.尝试在Controller内部查找异常处理方法来处理当前异常,未找到进入2 2.尝试寻找全局异常处理方法来处理当前异常,未找到则返回错误信息

Controller级异常处理

局部异常处理方法只能处理当前Controller中抛出的异常,示例如下:

@RestController
@RequestMapping("/exception")
public class LocalExceptionResolver {

    @RequestMapping("/willBeHandled")
    public void willBeHandled() {
        throw new IllegalArgumentException("IllegalArgumentException...");
    }

    @RequestMapping("/willNotBeHandled")
    public void willNotBeHandled() {
        throw new RuntimeException("RuntimeException...");
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public String handleLocalException(IllegalArgumentException ex) {
        return "HandleLocalException [" + ex.getMessage() + "]";
    }
}

handleLocalException(XXX)方法会处理当前类中所有的IllegalArgumentException异常。

@ControllerAdvice全局异常处理

通过@ControllerAdvice@RestControllerAdvice来标识全局异常处理类,并可通过相应的属性设置该全局异常处理类生效的范围。使用示例如下:

@RestControllerAdvice(basePackages = {"esa.restlight.samples.starter.exceptionhandler", "esa.restlight.samples.starter.controller"})
public class GlobalExceptionResolver {

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception ex) {
        return Result.ok();
    }

    static class Result {
        private int status;
        private String msg;

        static Result ok() {
            Result r = new Result();
            r.status = 200;
            return r;
        }
        
        // getter and setter
    }

}

如上所示, handleException(XXX)方法会处理esa.restlight.samples.starter.exceptionhandleresa.restlight.samples.starter.controller包中抛出的所有Exception

高级使用

为了让用户更方便的使用异常处理, 类似的我们支持像Controller上一样的去使用一些注解的功能如 @RequestParam, @RequestHeader@CookieValue等方便的进行参数绑定而不是自己手动的去Request里面取并做一次参数转换的操作。

eg:

@ControllerAdvice
public class GlobalExceptionResolver {

    @ExceptionHandler(Exception.class)
    public String handleException(@RequestParam("foo") String foo, Exception ex) {
        // do something here...
        return "HandleGlobalException [" + ex.getMessage() + "]";
    }

}

异步异常处理器

异常处理器可以类似Controller中异步处理一样完成异步的处理 Restlight异步支持

  • CompletionStage
  • ListenableFuture(Guava)

使用CompletionStage异步方式:

@ExceptionHanlder(Exception.class)
public CompletionStage<String> handleExcption(Exception ex) {
    return CompletableFuture.supplyAsync(() -> {
        // ...
        return "Hello Restlight!";
    });
}

ListenableFuture(Guava)同理。