springMVC @RestControllerAdvice注解使用方式

使用 @RestControllerAdvice 的主要场景包括:

  1. 全局异常处理:处理所有控制器中抛出的未捕获异常。
  2. 数据校验失败处理:处理 Bean Validation 校验失败的情况。
  3. 自定义响应:统一定义响应格式或错误信息。

@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 {
    @Override
    public 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;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public 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 {
    @Autowired
    private HandlerInterceptor permissionInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(permissionInterceptor)
                .addPathPatterns("/**") // 拦截所有请求
                .excludePathPatterns("/ignoreThis"); // 排除不需要拦截的请求
    }
}

然后你请求http://localhost:8080/user/1?auth=1

你会发现auth=1的时候拦截器放行

auth=0的时候会被拦截器拦截,并且抛出我们自定义的异常,然后自定义异常会被我们写的异常处理器监听到,最终给客户端返回没有权限

相关推荐
超级大只老咪1 小时前
数组相邻元素比较的循环条件(Java竞赛考点)
java
小浣熊熊熊熊熊熊熊丶1 小时前
《Effective Java》第25条:限制源文件为单个顶级类
java·开发语言·effective java
毕设源码-钟学长1 小时前
【开题答辩全过程】以 公交管理系统为例,包含答辩的问题和答案
java·eclipse
啃火龙果的兔子1 小时前
JDK 安装配置
java·开发语言
星哥说事2 小时前
应用程序监控:Java 与 Web 应用的实践
java·开发语言
派大鑫wink2 小时前
【JAVA学习日志】SpringBoot 参数配置:从基础到实战,解锁灵活配置新姿势
java·spring boot·后端
xUxIAOrUIII2 小时前
【Spring Boot】控制器Controller方法
java·spring boot·后端
Dolphin_Home2 小时前
从理论到实战:图结构在仓库关联业务中的落地(小白→中级,附完整代码)
java·spring boot·后端·spring cloud·database·广度优先·图搜索算法
醇氧2 小时前
org.jetbrains.annotations的@Nullable 学习
java·开发语言·学习·intellij-idea
Java&Develop2 小时前
Aes加密 GCM java
java·开发语言·python