全局异常处理 自定义异常 星云抛异常 throw new BasicRuntimeException @ControllerAdvice实现优雅地处理异常

不要再满屏写 try…catch 了!这个更香!

一、经研院自己实现的

1、自定义异常

import lombok.Getter;
import org.springframework.http.HttpStatus;

public class BasicRuntimeException extends RuntimeException {
    @Getter
    private Object errorMessages;
    @Getter
    private HttpStatus httpStatus;

    public BasicRuntimeException(Object errorMessages, HttpStatus httpStatus) {
        this.errorMessages = errorMessages;
        this.httpStatus = httpStatus;
    }
}

2、自定义异常处理

import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@ControllerAdvice
public class BasicRuntimeExceptionHandler {

    @ExceptionHandler(value = {Exception.class})
    @ResponseBody
    public ResponseEntity handleException(Exception ex) {
        Object message = "";

        //参数异常 要有这个不然@Valid失效
        if (ex instanceof MethodArgumentNotValidException) {
            BindingResult result = ((MethodArgumentNotValidException) ex).getBindingResult();
            assert result != null;
            List<ObjectError> list = result.getAllErrors();
            if (list.size() > 0) {
                message = list.get(0).getDefaultMessage();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", message);
                return new ResponseEntity<>(jsonObject, HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }

        //自定义的异常
        if (ex instanceof BasicRuntimeException) {
            BasicRuntimeException basicRuntimeException = (BasicRuntimeException) ex;
            message = basicRuntimeException.getErrorMessages();
            return new ResponseEntity<>(message, basicRuntimeException.getHttpStatus());
        }

        //JDK自带的异常
        if (ex instanceof RuntimeException) {
            RuntimeException runtimeException = (RuntimeException) ex;
            message = runtimeException.getMessage();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("message", message);
            return new ResponseEntity<>(jsonObject, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        return new ResponseEntity<Object>(message, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

3、使用自定义异常

if (optionalStructEntity.isEmpty()) {
            throw new BasicRuntimeException("异常信息,可以任何类型", HttpStatus.UNAUTHORIZED);
 }

二、星云

1、全局异常处理类

package com.lhc.exception;

import com.alibaba.fastjson.JSONObject;
import com.lhc.web.service.ExceptionMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@ControllerAdvice
public class CommonControllerAdvice extends ResponseEntityExceptionHandler {

    private final Logger log = LoggerFactory.getLogger(CommonControllerAdvice.class);

    private final ExceptionMessageService exceptionMessageService;

    public CommonControllerAdvice(ExceptionMessageService exceptionMessageService) {
        this.exceptionMessageService = exceptionMessageService;
    }


    @ExceptionHandler
    @ResponseBody
    ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
        String message;
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        try {
            status = getStatus(request);
            String moduleName = "";
            String code = "";
            Object[] args = {};
            if (ex instanceof BasicRuntimeException) {
                BasicRuntimeException basicRuntimeException = (BasicRuntimeException) ex;
                moduleName = basicRuntimeException.getModuleName();
                code = basicRuntimeException.getCode();
                args = basicRuntimeException.getArgs();
                message = exceptionMessageService.getMessage(moduleName, code, args);
                if ("UNAUTHORIZED".equals(code)) {
                    status = HttpStatus.UNAUTHORIZED;
                } else {
                    args = basicRuntimeException.getArgs();
                    message = exceptionMessageService.getMessage(moduleName, code, args);
                }
            } else {
                message = exceptionMessageService.getMessage(moduleName, code, args);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            message = "error";
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", message);
        return new ResponseEntity<>(jsonObject, status);
    }

    /**
     * Customize the response for MethodArgumentNotValidException.
     * <p>This method delegates to {@link #handleExceptionInternal}.
     *
     * @param ex      the exception
     * @param headers the headers to be written to the response
     * @param status  the selected response status
     * @param request the current request
     * @return a {@code ResponseEntity} instance
     */
    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers, HttpStatus status, WebRequest request) {
        String message = "";
        try {
            String defaultMessage;
            String moduleName = "";
            String code = "";
            defaultMessage = Objects.requireNonNull(ex.getBindingResult().getFieldError()).getDefaultMessage();
            if (!StringUtils.isEmpty(defaultMessage)) {
                if (defaultMessage.contains("_")) {
                    String[] strs = defaultMessage.split("_");
                    if (strs.length == 2) {
                        moduleName = strs[0];
                        code = strs[1];
                    }
                } else {
                    message = defaultMessage;
                }
            }
            if (StringUtils.isEmpty(message) && !StringUtils.isEmpty(moduleName) && !StringUtils.isEmpty(code)) {
                message = exceptionMessageService.getMessage(moduleName, code, null);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            message = "error";
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", message);
        return new ResponseEntity<>(jsonObject, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * Customize the response for BindException.
     * <p>This method delegates to {@link #handleExceptionInternal}.
     *
     * @param ex      the exception
     * @param headers the headers to be written to the response
     * @param status  the selected response status
     * @param request the current request
     * @return a {@code ResponseEntity} instance
     */
    @Override
    protected ResponseEntity<Object> handleBindException(
            BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        log.error(ex.getMessage(), ex);
        return handleExceptionInternal(ex, null, headers, status, request);
    }

    /**
     * 获取http状态码
     *
     * @param request HttpServletRequest
     * @return HttpStatus
     */
    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }
}

2、自定义异常类

package com.lhc.exception;

import lombok.Getter;

import java.util.Arrays;

/**
 * @Author lhc
 * @Date 2020-10-28 10:31
 **/
public class BasicRuntimeException extends RuntimeException  {
    @Getter
    private String moduleName;
    @Getter
    private String code;
    @Getter
    private Object[] args;

    public BasicRuntimeException(String moduleName, String code) {
        super(moduleName + "_" + code);
        this.moduleName = moduleName;
        this.code = code;
    }

    public BasicRuntimeException(String moduleName, String code, Object[] args) {
        super(moduleName + "_" + code + "_" + Arrays.toString(args));
        this.moduleName = moduleName;
        this.code = code;
        this.args = args;
    }
}

3、数据库表

CREATE TABLE `basic_exception_message` (
  `exm_id` char(32) NOT NULL COMMENT '异常消息管理ID',
  `exm_module_name` varchar(50) DEFAULT NULL COMMENT '模块名',
  `exm_code` int(11) NOT NULL COMMENT '异常消息编码',
  `exm_message` varchar(500) NOT NULL COMMENT '异常提示消息',
  `exm_language_id` char(32) NOT NULL DEFAULT '1' COMMENT '语言ID',
  `exm_is_default` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否默认| true 默认提示消息 false非默认提示消息',
  `exm_create_time` datetime NOT NULL COMMENT '创建时间',
  `exm_update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `exm_creator_id` char(32) NOT NULL COMMENT '创建人',
  `exm_update_operator_id` char(32) DEFAULT NULL COMMENT '更新人',
  `exm_is_available` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效',
  PRIMARY KEY (`exm_id`) USING BTREE,
  KEY `exm_module_name` (`exm_module_name`) USING BTREE,
  KEY `exm_code` (`exm_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='异常消息管理表';

4、常量类

package com.nebula.microservice.common.constant;

public class AppConstants {

    public interface ExceptionModel {
        String MODEL_MEMBER = "member";
        String MODEL_SYSTEM = "system";
    }

    public interface MemberExceptionCode{
        String CODE_10001 = "10001";// 会员信息为找到
        String CODE_10002 = "10002";// 会员参数未找到
        String CODE_10003 = "10003";// 非法会员参数:原因(检测参数是否必填,但是值为空 或者 检测参数ID和参数类型是否匹配)
        String CODE_10004 = "10004";
        String CODE_10005 = "10005";
        String CODE_10006 = "10006";
        String CODE_10007 = "10007";
        String CODE_10008 = "10008";
        String CODE_10009 = "10009";
    }

    public interface SystemExceptionCode{
        String CODE_10001 = "10001";// 字典未查到
        String CODE_10002 = "10002";// 协议未找到,请联系管理员配置
        String CODE_10003 = "10003";
        String CODE_10004 = "10004";
        String CODE_10005 = "10005";
        String CODE_10006 = "10006";
        String CODE_10007 = "10007";
        String CODE_10008 = "10008";
        String CODE_10009 = "10009";
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘然生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值