如何拦截spring aop中aspect抛出的异常

ama*_*man 3 java spring aspectj

有没有办法拦截异常并向最终客户显示有意义的消息?我正在尝试使用 spring AOP 授权我的 api,如果最终用户无权访问该 API,我将抛出异常。

@Aspect
public class AuthorizationAspect {
  @Pointcut("@annotation(AuthenticateAccount)")
    public void authorized() {}

   private boolean isAuthorized() {
   // logic to check is user is authorised to call the api
   }

    @Before("authorized()")
    public void beforeControllerCall(JoinPoint joinPoint) throws UnauthorizedException {

        if(!isAuthorized)) {
            throw new UnauthorizedException("You don't have rights over this API");
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

通过抛出异常,我能够阻止对 API 的访问,但它不会返回我试图抛出异常的有意义的消息。

有没有人处理过这样的用例并可以帮助我解决这个问题?

Aji*_*man 5

您可以使用全局异常处理@ControllerAdvice。创建自定义异常并从 Aspect 类抛出该异常。@ControllerAdvice您可以像这样创建带注释的类:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {UnauthorizedException.class})
    public ResponseEntity<Object> handleException(UnauthorizedException ex){
        return new ResponseEntity<Object>(
      ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN);
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑:

Spring Boot全局异常处理代码如下:

演示控制器.java

@RestController
public class DemoController {

    @GetMapping("/hello")
    String hello(){
        return "Message from controller if there is no exception";
    }
}
Run Code Online (Sandbox Code Playgroud)

AuthException.java

public class AuthException extends Exception{
    AuthException(String msg){
        super(msg);
    }
}
Run Code Online (Sandbox Code Playgroud)

AopValidator.java

@Aspect
@Component
public class AopValidator {

    @Before("execution(String hello())")
     public void test() throws AuthException{
         throw new AuthException("Exception message from AOP on unauthorized access");
     }
}
Run Code Online (Sandbox Code Playgroud)

GlobalExceptionHandler.java

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(AuthException.class)
    ResponseEntity<Object> handleException(AuthException ex){
        return new ResponseEntity<>(ex.getMessage(), new HttpHeaders(), HttpStatus.FORBIDDEN);
    }
}
Run Code Online (Sandbox Code Playgroud)