统一异常处理

        统一项目数据格式,统一异常管理便于更好的定位项目问题。
        由于自我实现有项目业务原因,把主要的接口与思路分享,可自由实现自我适合的业务异常链路。 
        核心思路:类似于filter责任链处理方式。
        chain :管理handler执行链路
        handler:处理特定异常的处理器(我使用自定义处理标记处理器);

abstract
    统一抽象异常类,抛出的自定义业务异常须继承此类
package com.ygy.exception.model;


import com.ygy.exception.enums.ExceptionCodeEnum;
import com.ygy.exception.enums.ModuleCodeEnum;
import com.ygy.exception.helper.ExceptionCodeHelper;

/**
 * Created by guoyao on 2018/2/23.
 * 自定义基础异常
 */
public abstract class AbstractException extends RuntimeException {


    public AbstractException(String msg) {
        super(msg);
        this.msg=msg;
    }

    public String getExceptionCode() {
        //异常code码
        ExceptionCodeEnum exceptionCodeEnum=getCodeEnum();

        //模块code码
        ModuleCodeEnum moduleEnum=getModuleCodeEnum();

        //错误子码
        String subCode=getSubCode();

        return ExceptionCodeHelper.getExceptionCode(exceptionCodeEnum,moduleEnum,subCode);
    }

    //模块码
    protected abstract ModuleCodeEnum getModuleCodeEnum();

    //异常类型
    protected abstract ExceptionCodeEnum getCodeEnum();

    //子错误码
    protected abstract String getSubCode();

    private String code;

    private String msg;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code=code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg=msg;
    }
}
helper
    异常码helper构建类
package com.ygy.exception.helper;

import com.ygy.exception.enums.ExceptionCodeEnum;
import com.ygy.exception.enums.ExceptionSubCodeEnum;
import com.ygy.exception.enums.ModuleCodeEnum;
import org.apache.commons.lang3.StringUtils;

/**
 * Created by guoyao on 2018/2/28.
 * 异常组合工具类
 */
public class ExceptionCodeHelper {


    /**
     * 获取默认异常码
     * @return
     */
    public static String getExceptionCode() {

        return getUnknownCode(ModuleCodeEnum.UNKNOWN_MODULE);
    }

    /**
     * 根据enum获取未知异常码
     * @return
     */
    public static String getUnknownCode(ModuleCodeEnum moduleCodeEnum) {
        return getExceptionCode(ExceptionCodeEnum.UNKNOWN_CDOE, moduleCodeEnum, ExceptionSubCodeEnum.ERP_UNKNOWN_EXCEPTION.getCode());
    }

    /**
     * 根据enum获取基础异常码
     *
     * @return
     */
    public static String getNormalCode(ModuleCodeEnum moduleCodeEnum, ExceptionSubCodeEnum exceptionSubCodeEnum) {

        return getExceptionCode(ExceptionCodeEnum.NORMAL_CDOE, moduleCodeEnum, exceptionSubCodeEnum.getCode());
    }

    /**
     * 根据enum获取业务异常码
     *
     * @return
     */
    public static String getBizCode(ModuleCodeEnum moduleCodeEnum, String subCode) {

        return getExceptionCode(ExceptionCodeEnum.BIZ_CDOE, moduleCodeEnum, subCode);
    }

    /**
     * 根据enum获取异常码
     * @param exceptionCodeEnum
     * @param moduleCodeEnum
     * @param subCode
     * @return
     */
    public static String getExceptionCode(ExceptionCodeEnum exceptionCodeEnum, ModuleCodeEnum moduleCodeEnum, String subCode) {
        if (exceptionCodeEnum == null) {
            exceptionCodeEnum=ExceptionCodeEnum.UNKNOWN_CDOE;
        }

        if (moduleCodeEnum == null) {
            moduleCodeEnum=ModuleCodeEnum.UNKNOWN_MODULE;
        }

        if (StringUtils.isEmpty(subCode)) {
            subCode=ExceptionSubCodeEnum.ERP_UNKNOWN_EXCEPTION.getCode();
        }
        return new StringBuilder().append(exceptionCodeEnum.getCode()).append(moduleCodeEnum.getCode()).append(subCode).toString();

    }
}
param
    异常传递参数,可自由添加自己项目中特有的异常追踪id,api_name等标记
package com.ygy.exception.model;

import com.ygy.exception.enums.ModuleCodeEnum;

/**
 * Created by guoyao on 2018/3/1.
 * 异常处理传递可选参数,可扩展
 */
public class ExceptionParams {


    private Object extraParam;

    private ModuleCodeEnum moduleCodeEnum;


    public Object getExtraParam() {
        return extraParam;
    }

    public ExceptionParams setExtraParam(Object extraParam) {
        this.extraParam=extraParam;
        return this;
    }

    public ModuleCodeEnum getModuleCodeEnum() {
        return moduleCodeEnum;
    }

    public ExceptionParams setModuleCodeEnum(ModuleCodeEnum moduleCodeEnum) {
        this.moduleCodeEnum=moduleCodeEnum;
        if (moduleCodeEnum == null) {
            this.moduleCodeEnum=ModuleCodeEnum.UNKNOWN_MODULE;
        }
        return this;
    }

}
handler
    业务异常执行器接口,可以进行特定异常的单独处理,也可以统一处理特定类型异常
package com.ygy.exception.handler;


import com.ygy.exception.model.ExceptionParams;
import com.ygy.exception.model.ResultBean;
import com.ygy.exception.chain.ExceptionHandlerChain;

/**
 * Created by guoyao on 2018/2/23.
 * 异常处理器,对特定异常处理方式。
 */
public interface ExceptionHandler {

    public ResultBean handlerException(Exception e, ExceptionParams params, ExceptionHandlerChain chain);

}
package com.ygy.exception.handler;

import com.ygy.exception.model.AbstractException;
import com.ygy.exception.model.ExceptionParams;
import com.ygy.exception.model.ResultBean;
import com.ygy.exception.annotation.ExceptionHandler;
import com.ygy.exception.chain.ExceptionHandlerChain;
import org.springframework.stereotype.Component;


/**
 * Created by guoyao on 2018/2/25.
 * 自定义业务异常 统一处理异常
 */
@Component
@ExceptionHandler(order = "100")
public class AbstractExceptionHandler implements com.ygy.exception.handler.ExceptionHandler {

    @Override
    public ResultBean handlerException(Exception e, ExceptionParams exceptionParams, ExceptionHandlerChain chain) {
        if (e instanceof AbstractException) {
            return  ResultBean.ofError((AbstractException) e, exceptionParams);
        }
       return chain.doHandler(e,exceptionParams);
    }
}







chain
    handler执行链路接口,管理加载的handler进行业务处理
package com.ygy.exception.chain;


import com.ygy.exception.model.ExceptionParams;
import com.ygy.exception.model.ResultBean;

/**
 * Created by guoyao on 2018/2/25.
 * 异常处理链接口,可自己实现链路处理方式
 */
public interface HandlerChain {

    public ResultBean doHandler(Exception e, ExceptionParams exceptionParams);

}
package com.ygy.exception.chain;


import com.ygy.exception.model.ExceptionParams;
import com.ygy.exception.model.ResultBean;
import com.ygy.exception.handler.ExceptionHandler;
import com.ygy.exception.handler.listener.ExceptionHandlerListener;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;

/**
 * Created by guoyao on 2018/2/25.
 * 异常处理链路
 */
@Component
@Scope("prototype")
public class ExceptionHandlerChain implements HandlerChain {

    private int cursor=0;

    @Resource
    ExceptionHandlerListener exceptionHandlerListener;


    public ResultBean doHandler(Exception e, ExceptionParams exceptionParams) {


        ArrayList<ExceptionHandler> handlers=exceptionHandlerListener.getHandlers();

        if (CollectionUtils.isEmpty(handlers)) {
            return ResultBean.ofError(exceptionParams);
        }

        if (cursor >= handlers.size()) {
            return ResultBean.ofError(exceptionParams,"系统异常,异常处理链路达到上限");
        }


        ResultBean resultBean=handlers.get(cursor++).handlerException(e, exceptionParams, this);

        if (resultBean == null) {
            resultBean = ResultBean.ofError(exceptionParams);
        }

        return resultBean;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot提供了一种简单而强大的方式来处理应用程序中的异常,即统一异常处理。通过统一异常处理,我们可以捕获和处理应用程序中的所有异常,并返回自定义的错误响应。 在Spring Boot中,我们可以使用@ControllerAdvice注解来定义一个全局的异常处理类。这个类可以包含多个异常处理方法,每个方法对应一个具体的异常类型。当应用程序中抛出对应的异常时,Spring Boot会自动调用相应的异常处理方法进行处理。 下面是一个简单的示例代码,演示了如何使用@ControllerAdvice来实现统一异常处理: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleException(Exception ex) { ErrorResponse errorResponse = new ErrorResponse(); errorResponse.setMessage("Internal Server Error"); errorResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(UserNotFoundException.class) public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex) { ErrorResponse errorResponse = new ErrorResponse(); errorResponse.setMessage("User Not Found"); errorResponse.setStatus(HttpStatus.NOT_FOUND.value()); return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND); } // 其他异常处理方法... } ``` 在上面的代码中,我们定义了两个异常处理方法:handleException和handleUserNotFoundException。handleException方法用于处理所有未被其他异常处理方法捕获的异常,而handleUserNotFoundException方法用于处理UserNotFoundException异常。 在每个异常处理方法中,我们可以根据具体的业务需求,创建一个自定义的错误响应对象,并将其封装在ResponseEntity中返回给客户端。这样,无论是哪种异常,都可以得到统一的错误响应。 需要注意的是,为了使统一异常处理生效,我们还需要在应用程序的配置类上添加@EnableWebMvc注解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值