日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

SpringBoot自定義異常處理機制

作者:何中應 更新時間: 2023-12-09 編程語言

說明:在完整的項目結構中,我們通常會創建一套自定義的異常處理機制,在系統可能出現異常的地方手動拋出這些異常,可以快速定位到異常代碼片段,提高系統的可維護性。

本文介紹在SpringBoot項目中,搭建一套自定義異常處理機制。

統一響應結果

首先,創建一個統一響應結果類,如下,用于統一后臺的返回結果,請求成功返回數據,請求失敗返回錯誤信息;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 后端統一返回結果
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 編碼:1成功 0和其他數字為失敗
     */
    private Integer code;

    /**
     * 錯誤信息
     */
    private String msg;

    /**
     * 數據
     */
    private T data;


    /**
     * 成功并返回
     *
     * @param <T>
     * @return
     */
    public static <T> Result<T> success() {
        Result<T> result = new Result<T>();
        result.code = 1;
        return result;
    }

    /**
     * 成功并返回數據
     *
     * @param object
     * @param <T>
     * @return
     */
    public static <T> Result<T> success(T object) {
        Result<T> result = new Result<T>();
        result.data = object;
        result.code = 1;
        return result;
    }

    /**
     * 失敗,并返回信息
     *
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> Result<T> error(String msg) {
        Result result = new Result();
        result.msg = msg;
        result.code = 0;
        return result;
    }
}

然后,創建兩個接口,用于用戶登錄,根據ID查找用戶,如下:

(controller層)

import com.hezy.pojo.entity.User;
import com.hezy.pojo.vo.Result;
import com.hezy.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/exception")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public Result login(@RequestBody User user){
        return userService.login(user);
    }

    @GetMapping("/get")
    public Result get(Integer id){
        return userService.getUser(id);
    }
}

(Service實現類,其中TODO表示待完成的部分)

import cn.hutool.core.util.ObjUtil;
import com.hezy.pojo.entity.User;
import com.hezy.pojo.vo.Result;
import com.hezy.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Override
    public Result login(User user) {
        // 對user進行校驗
        if (!ObjUtil.isAllNotEmpty(user, user.getUsername(), user.getPassword())) {
            return Result.error("非法參數異常");
        }

        // TODO 根據用戶名查詢數據庫,校驗該用戶是否存在
        if (true) {
            return Result.error("該用戶不存在");
        }

        // TODO 保存用戶信息到數據庫
        
        return Result.success(user);
    }

    @Override
    public Result getUser(Integer id) {
        // 對id進行校驗
        if (id == null || id < 0) {
            return Result.error("非法參數異常");
        }

        // TODO 根據用戶名查詢數據庫, 校驗用戶是否存在
        if (true) {
            return Result.error("該用戶不存在");
        }

        return Result.success(new User(id, "張三", "123456"));
    }
}

(用戶實體類)

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    private Integer id;

    /**
     * 賬號
     */
    private String username;

    /**
     * 密碼
     */
    private String password;
}

啟動項目,運行;

在這里插入圖片描述

(測試登錄接口,因為在if里面寫死了,所以返回錯誤信息)

在這里插入圖片描述


(測試獲取用戶對象接口,因為在if里面寫死了,所以返回錯誤信息)

在這里插入圖片描述

異常枚舉

接下來,對上面的異常進行統一處理。

首先,創建一個異常的枚舉類,里面包含了異常狀態碼,異常信息等,如下:

/**
 * 異常枚舉類
 */
public enum ExceptionEnum {

    PARAM_EXCEPTION(10001, "非法參數異常"),

    PARAM_LACK(10002, "參數不全異常"),

    UNKNOW_EXCEPTION(99999, "未知異常");

    private int status;

    private String message;

    ExceptionEnum(int status, String message) {
        this.status = status;
        this.message = message;
    }

    public int getStatus() {
        return status;
    }

    public String getMessage() {
        return message;
    }
}

自定義異常

創建一個自定義異常類,繼承RuntimeException類,如下:

import com.hezy.enums.ExceptionEnum;

/**
 * 自定義異常
 */
public class MyException extends RuntimeException{

    /**
     * 異常枚舉
     */
    private ExceptionEnum exceptionEnum;

    public MyException(ExceptionEnum exceptionEnum) {
        super(exceptionEnum.getMessage());
        this.exceptionEnum = exceptionEnum;
    }

    public ExceptionEnum getExceptionEnum() {
        return exceptionEnum;
    }

    /**
     * 手動拋出異常
     * @param exceptionEnum
     * @return
     */
    public static MyException throwException(ExceptionEnum exceptionEnum){
        return new MyException(exceptionEnum);
    }
}

再創建一個異常的controller,自定義捕獲對應的異常,并打印信息;

import com.hezy.enums.ExceptionEnum;
import com.hezy.pojo.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局異常處理器
 */
@RestControllerAdvice
@Slf4j
public class GlobalException {

    /**
     * 自定義異常
     * @param e
     * @return
     */
    @ExceptionHandler(MyException.class)
    public Result handleException(MyException e){
        log.error(e.getMessage());
        return Result.builder()
                .code(0)
                .msg(e.getExceptionEnum().getMessage())
                .build();
    }

    /**
     * 全局異常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e){
        log.error(e.getMessage());
        return Result.builder()
                .code(0)
                .msg(ExceptionEnum.UNKNOW_EXCEPTION.getMessage())
                .build();
    }
}

最后,對前面業務實現類里面的代碼進行修改,當參數校驗錯誤時,直接拋出異常,如下:

import cn.hutool.core.util.ObjUtil;
import com.hezy.enums.ExceptionEnum;
import com.hezy.exception.MyException;
import com.hezy.pojo.entity.User;
import com.hezy.pojo.vo.Result;
import com.hezy.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Override
    public Result login(User user) {
        // 對user進行校驗,其中user、username、password,都不能為空
        if (!ObjUtil.isAllNotEmpty(user, user.getUsername(), user.getPassword())) {
            throw new MyException(ExceptionEnum.PARAM_LACK);
        }

        // TODO 根據用戶名查詢數據庫,校驗該用戶是否存在
        if (true) {
            return Result.error("該用戶不存在");
        }

        // TODO 保存用戶信息到數據庫

        return Result.success(user);
    }

    @Override
    public Result getUser(Integer id) {
        // id == null,參數不全異常
        if (id == null) {
            throw new MyException(ExceptionEnum.PARAM_LACK);
        }

        // id < 0,非法參數異常
        if (id < 0) {
            throw new MyException(ExceptionEnum.PARAM_EXCEPTION);
        }

        // TODO 根據用戶名查詢數據庫, 校驗用戶是否存在
        if (true) {
            return Result.error("該用戶不存在");
        }

        return Result.success(new User(id, "張三", "123456"));
    }
}

啟動項目,測試;

(當user中的username為空時)

在這里插入圖片描述

在這里插入圖片描述

(當獲取對象的id < 0時)

在這里插入圖片描述

在這里插入圖片描述

當發生其他未知異常時,如post請求的接口,我們使用get方式發送時;

在這里插入圖片描述

就會被全局異常捕獲到,并在控制臺打印報錯信息;

在這里插入圖片描述

如果此時,需要新增一個異常,只需要在ExceptionEnum(異常枚舉類)中新增一個枚舉項即可,如下:

(新增一個登錄異常)

/**
 * 異常枚舉類
 */
public enum ExceptionEnum {

    PARAM_EXCEPTION(10001, "非法參數異常"),

    PARAM_LACK(10002, "參數不全異常"),
    
    LOGIN_EXCEPTION(10003, "登錄異常"),

    UNKNOW_EXCEPTION(99999, "未知異常");

    private int status;

    private String message;

    ExceptionEnum(int status, String message) {
        this.status = status;
        this.message = message;
    }

    public int getStatus() {
        return status;
    }

    public String getMessage() {
        return message;
    }
}

總結

通過異常枚舉類 + 自定義異常類 + SpringBoot的異常處理注解,可以實現對項目量身定做一套異常處理機制,根據項目中出現的異常,來返回對應的異常信息,非常方便。

原文鏈接:https://blog.csdn.net/qq_42108331/article/details/134778472

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新