springMVC @RestControllerAdvice注解使用方式
使用 @RestControllerAdvice
的主要场景包括:
- 全局异常处理:处理所有控制器中抛出的未捕获异常。
- 数据校验失败处理:处理 Bean Validation 校验失败的情况。
- 自定义响应:统一定义响应格式或错误信息。
@RestControllerAdvice
注解的类通常与以下组件结合使用:
@ExceptionHandler
:用于处理特定的异常类型。@ResponseStatus
:用于定义异常的HTTP状态。@ExceptionHandler
方法可以访问异常对象、请求对象(WebRequest
)、响应对象等,以构造合适的响应。
以下是一个简单的示例,演示如何使用 @RestControllerAdvice
:
java
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {// 处理自定义异常@ExceptionHandler(CustomException.class)public ResponseEntity<String> handleCustomException(CustomException ex, WebRequest request) {// 构造错误信息String error = "An error occurred: " + ex.getMessage();return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);}// 可以添加更多的异常处理方法
}
在这个示例中,GlobalExceptionHandler
类使用 @RestControllerAdvice
注解标记,使其成为全局异常处理器。类中的 handleCustomException
方法使用 @ExceptionHandler
注解标记,用于处理 CustomException
类型的异常。
使用 @RestControllerAdvice
可以集中处理异常,使控制器代码更简洁、更专注于业务逻辑,同时提高异常处理的可维护性。
一个模拟权限校验的案例
首先自定义一个权限不够的异常
public class PermissionException extends Exception{// 构造函数public PermissionException() {super();}public PermissionException(String message) {super(message);}public PermissionException(String message, Throwable cause) {super(message, cause);}public PermissionException(Throwable cause) {super(cause);}
}
然后用注解的方式写一个异常处理类
@RestControllerAdvice
public class PermissionExceptionHandler {@ExceptionHandler(PermissionException.class)public Map handleMyCustomException(PermissionException ex) {Map<String, String> msg = new HashMap<>();msg.put("status","500");msg.put("msg","错误,没有权限");return msg;}
}
然后写一个处理权限校验的拦截器
/*
* preHandle在执行处理器方法之前执行
* postHandle在执行处理器方法之后执行
* afterCompletion在这次请求完成后执行
* */
@Component
public class PermissionInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String auth = request.getParameter("auth");System.out.println(auth);if ("0".equals(auth)){throw new PermissionException();}//返回true放行,返回false不放行return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}
然后把拦截器注册到spring中
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate HandlerInterceptor permissionInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(permissionInterceptor).addPathPatterns("/**") // 拦截所有请求.excludePathPatterns("/ignoreThis"); // 排除不需要拦截的请求}
}
然后你请求http://localhost:8080/user/1?auth=1
你会发现auth=1的时候拦截器放行
auth=0的时候会被拦截器拦截,并且抛出我们自定义的异常,然后自定义异常会被我们写的异常处理器监听到,最终给客户端返回没有权限