统一异常处理

具体实现

1  定义结果状态信息

项目中我们会将接口返回的数据封装成Json数据格式,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致、轻松。一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容。

所以我们需要创建统一返回结果状态信息的枚举类

当然,这个是每个项目不同的,需要实际情况实际分析!!!!

package com.atguigu.ssyx.common.result;

import lombok.Data;
import lombok.Getter;
/**
 * 统一返回结果状态信息类
 *
 */
@Getter
public enum ResultCodeEnum {

    SUCCESS(200,"成功"),
    FAIL(201, "失败"),
    SERVICE_ERROR(2012, "服务异常"),
    DATA_ERROR(204, "数据异常"),
    ILLEGAL_REQUEST(205, "非法请求"),
    REPEAT_SUBMIT(206, "重复提交"),

    LOGIN_AUTH(208, "未登陆"),
    PERMISSION(209, "没有权限"),

    ORDER_PRICE_ERROR(210, "订单商品价格变化"),
    ORDER_STOCK_FALL(204, "订单库存锁定失败"),
    CREATE_ORDER_FAIL(210, "创建订单失败"),

    COUPON_GET(220, "优惠券已经领取"),
    COUPON_LIMIT_GET(221, "优惠券已发放完毕"),

    URL_ENCODE_ERROR( 216, "URL编码失败"),
    ILLEGAL_CALLBACK_REQUEST_ERROR( 217, "非法回调请求"),
    FETCH_ACCESSTOKEN_FAILD( 218, "获取accessToken失败"),
    FETCH_USERINFO_ERROR( 219, "获取用户信息失败"),


    SKU_LIMIT_ERROR(230, "购买个数不能大于限购个数"),
    REGION_OPEN(240, "该区域已开通"),
    REGION_NO_OPEN(240, "该区域未开通"),
    ;

    private Integer code;

    private String message;

    private ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

2  创建统一返回结果类

这里我们封装了要返回结果都所有信息,包括状态值code,状态信息message,以及数据data

package com.atguigu.ssyx.common.result;

import lombok.Data;

@Data
public class Result<T> {

    //状态码
    private Integer code;
    //信息
    private String message;
    //数据
    private T data;

    //构造私有化
    private Result() { }

    //设置数据,返回对象的方法
    public static<T> Result<T> build(T data,ResultCodeEnum resultCodeEnum) {
        //创建Resullt对象,设置值,返回对象
        Result<T> result = new Result<>();
        //判断返回结果中是否需要数据
        if(data != null) {
            //设置数据到result对象
            result.setData(data);
        }
        //设置其他值
        result.setCode(resultCodeEnum.getCode());
        result.setMessage(resultCodeEnum.getMessage());
        //返回设置值之后的对象
        return result;
    }

    //成功的方法
    public static<T> Result<T> ok(T data) {
        Result<T> result = build(data, ResultCodeEnum.SUCCESS);
        return result;
    }

    //失败的方法
    public static<T> Result<T> fail(T data) {
        return build(data,ResultCodeEnum.FAIL);
    }
}

3  编写统一异常处理类

系统在运行过程中如果出现了异常,默认会直接返回异常信息,比如500错误提示。但是我们想让异常结果也显示为统一的返回结果对象,并且统一处理系统的异常信息,那么需要进行统一异常处理。

3.1  代码

package com.atguigu.ssyx.common.exception;

import com.atguigu.ssyx.common.result.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        e.printStackTrace();
        return Result.fail(null);
    }

    /**
     * 自定义异常处理方法
     * @param e
     * @return
     */
    @ExceptionHandler(SsyxException.class)
    @ResponseBody
    public Result error(SsyxException e){
        return Result.fail(null);
    }
}

3.2  具体分析

@ControllerAdvice

@ControllerAdvice 在 Spring 框架中发挥了中心化异常处理的作用。它允许你定义一个或多个全局异常处理器,这些处理器可以捕获和处理应用程序中所有控制器(@Controller@RestController 注解的类)抛出的异常。以下是 @ControllerAdvice 发挥的一些关键作用:

  1. 集中管理异常处理逻辑:通过在一个地方定义异常处理逻辑,你可以避免在每个控制器中重复相同的代码,这有助于保持代码的整洁和可维护性。

  2. 统一异常响应格式:你可以定义一个统一的响应格式来处理所有的异常,这有助于客户端更容易地解析和处理错误。

  3. 减少代码冗余:不需要在每个控制器方法中添加异常处理代码,减少了代码的冗余。

  4. 提高代码的可重用性:定义的异常处理逻辑可以在多个控制器之间共享,提高了代码的可重用性。

  5. 增强错误处理的灵活性:你可以根据不同的异常类型定义不同的处理逻辑,甚至可以根据异常的属性(如错误代码或错误消息)来定制响应。

  6. 支持注解驱动的异常处理:通过使用 @ExceptionHandler 注解,你可以轻松地将特定的异常处理方法与特定的异常类型关联起来。

  7. 支持条件化配置:你可以使用 basePackagesbasePackageClasses 属性来指定 @ControllerAdvice 应该应用于哪些控制器,或者使用 @Profile 注解来根据环境条件启用或禁用特定的异常处理器。

  8. 支持响应体的定制:通过 @ResponseBody 注解,你可以将异常处理方法的返回值直接作为 HTTP 响应体返回,这对于构建 RESTful 服务非常有用。

  9. 支持异常的转换:你可以将捕获的异常转换为自定义的异常类型,然后由全局异常处理器统一处理,这样可以隐藏内部实现细节,只向客户端暴露必要的错误信息。

  10. 支持异步处理:在某些情况下,异常处理可能需要执行一些异步操作,@ControllerAdvice 支持这种场景,使得异常处理更加灵活。

总的来说,@ControllerAdvice 提供了一个强大而灵活的机制,用于集中处理 Spring 应用程序中的异常,从而简化了错误处理逻辑的编写和维护。

@ExceptionHandler

@ExceptionHandler 注解在 Spring 框架中用于指定某个方法用于处理特定的异常类型。当你在 @ControllerAdvice@RestControllerAdvice 注解的类中使用 @ExceptionHandler 注解时,你可以定义一个方法来专门处理被注解指定的异常。

对于 @ExceptionHandler(SsyxException.class),这个注解的作用是:

  1. 指定异常类型SsyxException 是一个自定义异常类(假设它已经在你的应用程序中定义)。@ExceptionHandler 注解告诉 Spring,当 SsyxException 被抛出时,应该调用标记了这个注解的方法来处理这个异常。

  2. 异常处理方法:被 @ExceptionHandler(SsyxException.class) 注解的方法将作为处理 SsyxException 的处理器。这个方法可以返回一个 ResponseEntity 对象,这样就可以自定义响应的状态码、头部信息和响应体。

  3. 集中处理:通过在 @ControllerAdvice 注解的类中定义 @ExceptionHandler 方法,你可以集中处理特定类型的异常,而不是在每个控制器中单独处理。

  4. 定制响应:你可以在 @ExceptionHandler 方法中定制异常的响应,例如返回错误信息、错误代码或者其他对客户端有用的信息。

4  自定义异常处理

@Data
public class SsyxException extends RuntimeException{

    //异常状态码
    private Integer code;

    /**
     * 通过状态码和错误消息创建异常对象
     * @param message
     * @param code
     */
    public SsyxException(String message, Integer code) {
        super(message);
        this.code = code;
    }

    /**
     * 接收枚举类型对象
     * @param resultCodeEnum
     */
    public SsyxException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }

    @Override
    public String toString() {
        return "GuliException{" +
                "code=" + code +
                ", message=" + this.getMessage() +
                '}';
    }
}

项目结构概览

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值