jck28 - 小柒 - 后端接口基本开发 - spring boot统一异常处理

一, 异常分类

  • 异常可以处理则为 CheckedException
  • 对于异常来说是无能为力的则为 RuntimeException
  • 想要异常结果也显示为统一的返回结果对象,并且统一处理系统的异常信息
  • 需要统一异常处理

二, 新建一个异常处理类

package com.ceshiren.springtest.core;

import com.ceshiren.springtest.exception.ServiceException;
import com.ceshiren.springtest.util.Result;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
//sping boot 3.x版本导入的servlet依赖为jakarta
//import jakarta.servlet.http.HttpServletRequest;


//ControllerAdvice  AOP面向切面编程,对原来对功能没有侵入性,原来什么样子现在还是什么样子
//我只是在原来的功能的基础上给你扩展出一个功能,统一异常处理功能
//@ControllerAdvice
//spring boot 3.x版本必须要加上Hidden注解,不然访问swagger-ui页面会报错
@Hidden
@RestControllerAdvice
public class GlobalExceptionHandler {

    String tips = "系统繁忙,请稍后重试";

    @ExceptionHandler({Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
//    @ResponseBody
    public Result exceptionHandler(Exception e){
        //记录日志,通知运维,通知开发
        //控制台打印异常,万一出现异常调试
        e.printStackTrace();
        return Result.error().message("非业务异常 "+ tips);
    }


    //自定义ServiceException异常,是一个运行时的异常
    @ExceptionHandler({ServiceException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result servceExceptionHandler(HttpServletRequest req, ServiceException se){
        String requestUrl = req.getRequestURI();
        String method = req.getMethod();
        se.printStackTrace();
        //前端页面展示的message异常内容
        return Result.error().message("业务异常 "+ tips
                +"RestAPI:"+method + " "+ requestUrl).code(se.getCode());
    }


    // .ArithmeticException - 计算溢出或者除数为0的异常
    @ExceptionHandler({ArithmeticException.class})
    public Result exceptionHandlerArithmetic(ArithmeticException e){
        e.printStackTrace();
        return Result.error().message("除数不能为0");
    }

}

三,自定义异常类

package com.ceshiren.springtest.exception;

public final class ServiceException extends RuntimeException{
    /**
     * 业务错误码
     */
    private Integer code;
    /**
     * 错误提示
     */
    private String message;

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

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

    public Integer getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

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

}

四,模拟手动抛出异常

package com.ceshiren.springtest.controller;

import com.ceshiren.springtest.exception.ServiceException;
import com.ceshiren.springtest.util.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "异常处理")
@RestController
public class ExceptionController {
    @Operation(description = "除数为0的异常")
    @GetMapping("/except/test")
    String exceptTest() {
        int a = 1 / 0;
        return "hello except" + a;
    }

    @Operation(description = "自定义ServiceException异常")
    @GetMapping("/modify/except")
    Result modifyExcept() {
        throw new ServiceException("无广告返回",1003);

    }
}