springboot中异常全局统一处理

个人博客

日常后端业务开发中,在提供接口服务时会遇到各种异常处理,通常涉及到参数校验异常、自定义异常以及一些不可预知的异常等等。下面就来说一下在springboot中如何在接口层进行全局性的异常处理。

全局异常处理

全局异常处理借用springmvc中的@ControllerAdvice注解来实现,当然在springboot中我们就用@RestControllerAdvice(内部包含@ControllerAdvice和@ResponseBody的特性)。此注解用来监听controller层抛出的异常,以至于让我们能进一步对异常做处理。

下面给出一个全局异常处理案例代码,涉及的有validaton注解校验的异常处理,自定义异常的处理,未知异常的处理。

注意:异常的handler域是由小至大的,所以有先后顺序。

package com.lazycece.sbac.exception.controller;

import com.lazycece.sbac.exception.exception.AbstractGlobalException;
import com.lazycece.sbac.exception.response.ResCode;
import com.lazycece.sbac.exception.response.ResMsg;
import com.lazycece.sbac.exception.response.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.ServletException;


/**
 * @author lazycece
 * @date 2019/02/23
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 参数校验错误异常
     *
     * @param e MethodArgumentNotValidException|BindException
     * @return ResponseData
     */
    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
    public ResponseData bindExceptionHandler(Exception e) {
        BindingResult bindingResult;
        if (e instanceof BindException) {
            bindingResult = ((BindException) e).getBindingResult();
        } else {
            bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
        }
        StringBuilder stringBuilder = new StringBuilder();
        bindingResult.getAllErrors().forEach(
                objectError ->
                        stringBuilder.append(",").append(objectError.getDefaultMessage())
        );
        String errorMessage = stringBuilder.toString();
        errorMessage = errorMessage.substring(1, errorMessage.length());
        return ResponseData.builder().code(ResCode.FAIL).message(errorMessage).build();
    }

    /**
     * 捕获自定义的统一全局异常
     *
     * @param e AbstractGlobalException
     * @return ResponseData
     */
    @ExceptionHandler(value = AbstractGlobalException.class)
    public ResponseData customExceptionHandler(AbstractGlobalException e) {
        return ResponseData.builder().code(e.getCode()).message(e.getMessage()).build();
    }

    /**
     * 捕获未知异常
     *
     * @param e Exception
     * @return ResponseData
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseData commonExceptionHandler(Exception e) throws ServletException {
        if (e instanceof ServletException) {
            throw (ServletException) e;
        }
        log.error("server inner error: {}", e);
        return ResponseData.builder().code(ResCode.FAIL).message(ResMsg.SERVER_INNER_ERROR).build();
    }
}

案例源码

案例源码地址:https://github.com/lazycece/springboot-actual-combat/tree/master/springboot-ac-exception

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值