springboot封装全局业务异常

1、准备工作

1.1 定义返回状态码,通常无异常返回200,业务异常返回500

package com.hwh.constant;

/**
 * 返回状态码
 *
 * @author heweihui
 */
public class HttpStatus {

    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功,但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;

}

1.2 定义业务异常ServiceException继承RuntimeException

package com.hwh.exception;

/**
 * 业务异常类
 *
 * @author heweihui
 */
public class ServiceException extends RuntimeException{

    private static final long serialVersionUID = -999820107846632460L;

    /**
     * 错误码
     */
    private Integer code;

    /**
     * 错误提示
     */
    private String message;

    public Integer getCode() {
        return code;
    }

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

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public ServiceException() {
    }

    public ServiceException(String message) {
        this.message = message;
    }

    public ServiceException(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

}

1.3 定义返回结果类ResponseResult

package com.hwh.entity;

import com.hwh.constant.HttpStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResponseResult {
    private int code;
    private String message;
    private Object data;

    public static ResponseResult success(){
        return success("success");
    }

    public static ResponseResult success(String message){
        return success(message, null);
    }

    public static ResponseResult success(Object data){
        return success(null, data);
    }

    public static ResponseResult success(String message, Object data){
        return new ResponseResult(HttpStatus.SUCCESS, message, data);
    }

    public static ResponseResult error(){
        return error("error");
    }

    public static ResponseResult error(String message){
        return error(message, null);
    }

    public static ResponseResult error(String message, Object data){
        return new ResponseResult(HttpStatus.ERROR, message, data);
    }

    public static ResponseResult error(int code, String message){
        return new ResponseResult(code, message, null);
    }
}

1.4 定义全局异常处理器GlobalExceptionHandler

package com.hwh.advice;

import com.hwh.entity.ResponseResult;
import com.hwh.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理器
 *
 * @author heweihui
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 业务异常
     */
    @ExceptionHandler(ServiceException.class)
    public ResponseResult handleServiceException(ServiceException e, HttpServletRequest request)
    {
        log.error(e.getMessage(), e);
        Integer code = e.getCode();
        return code == null ? ResponseResult.error(code, e.getMessage()) : ResponseResult.error(e.getMessage());
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public ResponseResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestURI, e);
        return ResponseResult.error(e.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public ResponseResult handleException(Exception e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return ResponseResult.error(e.getMessage());
    }
}

1.5 定义ErrorCode枚举类,存储业务异常编码跟异常信息

package com.hwh.error;

public enum ErrorCode {

    REQUEST_PARAM_ERROR(1001, "请求参数不正确");

    private int code;
    private String message;

    ErrorCode(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

2、准备工作就绪,下面编写service类进行测试

2.1 定义TestService类,模拟一个业务异常跟一个未知异常

package com.hwh.service;

import com.hwh.error.ErrorCode;
import com.hwh.exception.ServiceException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 *
 * @author heweihui
 */
@Service
public class TestService {
    public void TestException(String param){
        //业务异常
        if(StringUtils.isEmpty(param)){
            throw new ServiceException(ErrorCode.REQUEST_PARAM_ERROR.getCode(),
                    ErrorCode.REQUEST_PARAM_ERROR.getMessage());
        }
        //未知异常
        int i = 1 / 0;
        System.out.println(i);
    }
}

2.2 变成测试controller进行测试

@GetMapping("testException")
    public void testException(@RequestParam(value = "param1", required = false) String param1){
        testService.TestException(param1);
    }

3、postman测试

3.1 不传递参数param1

 3.2 正常传递参数param1

 下篇在此基础上写基于Validation进行参数校验封装,继续加油吧!


版权声明:本文为hui008原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。