当前位置: 代码网 > it编程>编程语言>Java > Spring Boot中的全局异常处理:@RestControllerAdvice的应用

Spring Boot中的全局异常处理:@RestControllerAdvice的应用

2024年08月02日 Java 我要评论
是Spring MVC提供的一个功能强大的注解,用于全局处理控制器中的异常。它相当于和:处理特定的异常,并将响应返回给前端。:预处理Web请求数据的绑定。:将数据绑定到模型中,以便在控制器的方法中使用。自动被Spring的组件扫描机制检测到,若应用通过MVC命令空间或MVC Java编程方式配置,该功能默认自动开启。

在现代web开发中,异常处理是一个不可或缺的部分。良好的异常处理不仅能提高系统的健壮性,还能提升用户体验。在spring boot中,全局异常处理的实现可以通过使用@restcontrolleradvice注解来完成。本文将详细介绍如何使用@restcontrolleradvice@exceptionhandler来统一处理异常,并给出具体的实现示例。

1. @restcontrolleradvice概述

@restcontrolleradvice是spring mvc提供的一个功能强大的注解,用于全局处理控制器中的异常。它相当于@controlleradvice@responsebody的组合,可以用于定义以下三种功能:

  1. @exceptionhandler:处理特定的异常,并将响应返回给前端。
  2. @initbinder:预处理web请求数据的绑定。
  3. @modelattribute:将数据绑定到模型中,以便在控制器的@requestmapping方法中使用。

@restcontrolleradvice自动被spring的组件扫描机制检测到,若应用通过mvc命令空间或mvc java编程方式配置,该功能默认自动开启。

2. 实现全局异常处理

在实现全局异常处理时,我们通常会定义一个异常处理类,这个类中包含多个异常处理方法,每个方法对应一种或多种异常类型。下面是一个典型的实现示例。

2.1 全局异常处理器

import com.sugon.cloud.lowcode.result.returnresult;
import lombok.extern.slf4j.slf4j;
import org.mybatis.spring.mybatissystemexception;
import org.springframework.web.httprequestmethodnotsupportedexception;
import org.springframework.web.bind.annotation.exceptionhandler;
import org.springframework.web.bind.annotation.responsebody;
import org.springframework.web.bind.annotation.restcontrolleradvice;

import javax.naming.authenticationexception;
import javax.servlet.http.httpservletrequest;

import static com.sugon.cloud.lowcode.constants.splitcharacter.left_parentheses;
import static com.sugon.cloud.lowcode.constants.splitcharacter.right_parentheses;
import static com.sugon.cloud.lowcode.result.codemessageenum.*;

@restcontrolleradvice
@slf4j
public class globalexceptionhandler {

  @exceptionhandler(value = bizexception.class)
  @responsebody
  public returnresult bizexceptionhandler(httpservletrequest req, bizexception e) {
    log.error("发生业务异常: {}, 请求接口: {}", e.getmessage(), req.getrequesturi());
    return returnresult.error(e.getcode(), e.getmessage());
  }

  @exceptionhandler(value = nullpointerexception.class)
  @responsebody
  public returnresult exceptionhandler(httpservletrequest req, nullpointerexception e) {
    log.error("空指针异常信息: {}, 请求接口: {}", e, req.getrequesturi());
    return returnresult.error(
        null_point_error_exception.getcode(),
        null_point_error_exception.getmessage()
            + right_parentheses
            + e.getmessage()
            + left_parentheses);
  }

  @exceptionhandler(value = httprequestmethodnotsupportedexception.class)
  @responsebody
  public returnresult methodnotsupportedexceptionhandler(httpservletrequest req, exception e) {
    log.error("请求方法异常信息: {},请求接口: {}", e, req.getrequesturi());
    return returnresult.error(
        request_method_error.getcode(),
        request_method_error.getmessage() + right_parentheses + e.getmessage() + left_parentheses);
  }

  @exceptionhandler(value = mybatissystemexception.class)
  @responsebody
  public returnresult sqlsyntaxerrorexceptionhandler(httpservletrequest req, exception e) {
    log.error("mybatis系统异常信息: {},请求接口: {}", e, req.getrequesturi());
    return returnresult.error(
        inner_frame_exception.getcode(),
        inner_frame_exception.getmessage() + right_parentheses + e.getmessage() + left_parentheses);
  }

  @exceptionhandler(value = authenticationexception.class)
  public returnresult incorrectcredentialsexception(
      httpservletrequest request, authenticationexception e) {
    log.error("用户名或密码不正确: {}, 请求接口: {}", e, request.getrequesturi());
    return returnresult.error(user_credentials_error);
  }

  @exceptionhandler(value = userexception.class)
  public returnresult incorrectuserexception(httpservletrequest request, userexception e) {
    log.error("用户信息异常: {}, 请求接口: {}", e, request.getrequesturi());
    return returnresult.error(e.getcode(), e.getmessage());
  }

  @exceptionhandler(value = exception.class)
  @responsebody
  public returnresult exceptionhandler(httpservletrequest req, exception e) {
    e.printstacktrace();
    log.error("未知异常: {}, 请求接口: {}", e, req.getrequesturi());
    return returnresult.error(
        internal_server_error.getcode(),
        internal_server_error.getmessage() + right_parentheses + e.getmessage() + left_parentheses);
  }
}

2.2 自定义业务异常类

import com.sugon.cloud.lowcode.result.baseresultinterface;
import com.sugon.cloud.lowcode.result.codemessageenum;
import io.swagger.annotations.apimodel;
import io.swagger.annotations.apimodelproperty;

@apimodel(description= "业务异常数据")
public class bizexception extends runtimeexception implements baseresultinterface {

    private static final long serialversionuid = 1l;

    @apimodelproperty(value = "错误码")
    private string code;

    @apimodelproperty(value = "错误信息")
    private string message;

    public bizexception() {
        super();
    }

    public bizexception(codemessageenum codemessageenum) {
        super(codemessageenum.getcode());
        this.code = codemessageenum.getcode();
        this.message = codemessageenum.getmessage();
    }

    public bizexception(codemessageenum codemessageenum, throwable cause) {
        super(codemessageenum.getcode(), cause);
        this.code = codemessageenum.getcode();
        this.message = codemessageenum.getmessage();
    }

    public bizexception(codemessageenum codemessageenum, string message, throwable cause) {
        super(codemessageenum.getcode(), cause);
        this.code = codemessageenum.getcode();
        this.message = message;
    }

    public bizexception(string message) {
        super(message);
        this.message = message;
    }

    public bizexception(string code, string message) {
        super(code);
        this.code = code;
        this.message = message;
    }

    public bizexception(string code, string message, throwable cause) {
        super(code, cause);
        this.code = code;
        this.message = message;
    }

    @override
    public throwable fillinstacktrace() {
        return this;
    }

    @override
    public string getcode() {
        return this.code;
    }

    @override
    public string getmessage() {
        return this.message;
    }
}

3. 统一返回格式

在上述代码中,所有的异常处理方法返回的是returnresult对象,它封装了返回给前端的数据。returnresult类的设计使得前端可以统一解析和展示错误信息。

3.1 返回结果类

import com.alibaba.fastjson.jsonobject;
import io.swagger.annotations.apimodel;
import io.swagger.annotations.apimodelproperty;
import lombok.getter;
import lombok.setter;

import static com.sugon.cloud.lowcode.result.codemessageenum.*;

@setter
@getter
@apimodel(description= "返回响应数据")
public class returnresult<t> {

  @apimodelproperty(value = "状态码")
  private string code;

  @apimodelproperty(value = "响应信息")
  private string message;

  @apimodelproperty(value = "响应对象")
  private t result;

  @apimodelproperty(value = "是否成功")
  private boolean success = true;

  public returnresult() {}

  public returnresult(codemessageenum codemessageenum) {
    this.code = codemessageenum.getcode();
    this.message = codemessageenum.getmessage();
  }

  public static returnresult success() {
    return success(null);
  }

  public static <t> returnresult<t> success(t data) {
    return success(success, data);
  }

  public static <t> returnresult<t> loginsuccess(t data) {
    return success(success_login, data);
  }

  public static returnresult loginoutsuccess() {
    return success(success_logout, null);
  }

  private static <t> returnresult<t> success(codemessageenum codemessageenum, t data) {
    returnresult<t> result = new returnresult<>();
    result.setcode(codemessageenum.getcode());
    result.setmessage(codemessageenum.getmessage());
    result.setresult(data);
    return result;
  }

  public static returnresult error(codemessageenum codemessageenum) {
    return error(codemessageenum.getcode(), codemessageenum.getmessage());
  }

  public static returnresult error(codemessageenum codemessageenum, string message) {
    return error(codemessageenum.getcode(), message);
  }

  public static returnresult error(string code, string message) {
    returnresult result = new returnresult();
    result.setcode(code);
    result.setmessage(message);
    result.setsuccess(false);
    return result;
  }

  @override
  public string tostring() {
    return jsonobject.tojsonstring(this);
  }
}

4. 总结

通过@restcontrolleradvice@exceptionhandler,我们可以在spring boot应用中实现全局异常处理,统一管理和处理所有异常。这样不仅可以

减少重复代码,还能使代码更加整洁,提高可维护性。同时,通过统一的返回格式,前端处理响应数据时也能更加方便。

希望这篇文章对您在spring boot中实现全局异常处理有所帮助。如有任何问题或建议,欢迎交流探讨。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com