Springboot的異常處理與自定義異常


園友們好,元旦很快就到來了,提前祝各位園友們元旦快樂,今天給大家分享一個工作中必用一個知識點,就是使用枚舉構建自定義異常並應用於springboot的異常處理器。開始之前我先把這個案例的結構大致說明一下:

1、使用idea創建一個springboot的Gradle/Maven項目,引入web模塊即可(由於案例的重點是異常處理,所以跳過其他操作)。

2、創建一個javabean,用來接收前台的參數。

3、創建一個枚舉、封裝異常的錯誤碼等信息。

4、創建一個自定義異常類繼承RuntimeException。

5、創建一個controller,用來處理用戶請求。

6、創建一個springboot的異常處理類。

7、運行項目,測試。

OK、接下來就進入正題,先來第一步,創建項目(創建項目的過程就不需要一一演示了吧,^_^),下面是創建項目之后的Gradle項目中build.gradle中的依賴:

1 dependencies {
2     implementation('org.springframework.boot:spring-boot-starter-web')
3     testImplementation('org.springframework.boot:spring-boot-starter-test')
4 }

如果各位讀者是maven項目的話,pom.xml文件中的依賴應該長這樣子:

 1 <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-web</artifactId>
 5         </dependency>
 6 
 7         <dependency>
 8             <groupId>org.springframework.boot</groupId>
 9             <artifactId>spring-boot-starter-test</artifactId>
10             <scope>test</scope>
11         </dependency>
12     </dependencies>

ok,下面開始第二步,創建一個javabean:

package com.maolinjava.entity;

import java.io.Serializable;

/**
 * Created by tml on 2018/12/28.
 */
public class User implements Serializable {
    
    private String username;
    
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

ok,再來第三步,創建一個枚舉、封裝異常的錯誤碼等信息:

package com.maolinjava.commons.constant;

/**
 * Created by tml on 2018/12/28.
 */
public enum ServiceErrCode {

    REQ_PARAM_ERR(10001,"請求參數異常"),
    NOTFOUND_RESULT_ERR(10004,"未找到結果");

    private int code;

    ServiceErrCode(int code,String msg){
        this.code = code;
    }

    public int getCode() {
        return code;
    }
}

再來第四步、創建自定義異常類:

package com.maolinjava.commons.exception;

import com.maolinjava.commons.constant.ServiceErrCode;

/**
 * Created by tml on 2018/12/28.
 */
public class BaseServiceException extends RuntimeException {

    private int code;

    public BaseServiceException(String message, ServiceErrCode serviceErrCode) {//構造器的第二個參數是上面創建的那個枚舉,之后把枚舉里面定義的code給了這個code
        super(message);
        this.code = serviceErrCode.getCode();
    }

    public int getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return super.getMessage();
    }
}

第五步,創建一個controller:

package com.maolinjava.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.maolinjava.commons.constant.ServiceErrCode;
import com.maolinjava.commons.exception.BaseServiceException;
import com.maolinjava.entity.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * Created by tml on 2018/12/28.
 */
@RestController
public class UserController {

    @Resource
    private ObjectMapper jsonMapper;

    @PostMapping("/login")
    public ObjectNode login(@RequestBody(required = false) User user){
        //如果用戶發起的請求參數中user為null的話,就會拋出自定義的異常,之后會被全局的異常處理器所攔截響應到前端
        if(Objects.isNull(user)){
            throw new BaseServiceException("用戶為空,請填寫用戶名和密碼", ServiceErrCode.REQ_PARAM_ERR);
        }
        //如果輸入了用戶名和密碼則正常把輸入的信息響應回去
        System.out.println(user);
        return jsonMapper.createObjectNode().putPOJO("data",user);
    }

}

 

OK,再來第六步、創建一個springboot的異常處理類:

package com.maolinjava.commons.exception.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.maolinjava.commons.exception.BaseServiceException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.annotation.Resource;

/**
 * Created by tml on 2018/12/28.
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Resource
    private ObjectMapper jsonMapper;

    @ExceptionHandler(BaseServiceException.class)
    public ObjectNode baseServiceException(BaseServiceException e){
        int code = e.getCode();
        String msg = e.getMessage();
        return jsonMapper.createObjectNode().put("code",code).put("msg",msg);
    }

}

這個異常處理類主要用到的兩個注解是@RestControllerAdvice和@ExceptionHandler(xxx.class),說明一下:@RestControllerAdvice注解表示全局的異常通知,里面的value屬性可以指定一個異常通知的包范圍,一般這個不用去指定,就讓他對全部的包進行掃描即可;@ExceptionHandler(xxx.class)這個注解加在方法上,表示要攔截的某個異常並對該異常進行處理,里面的參數是要攔截的異常的類型,我這里攔截的是BaseServiceException這個異常,如果程序中有拋出BaseServiceException的地方就會進入該方法進行處理。

代碼已經全部OK,啟動項目,打開postman訪問 localhost:8080/login,附一張postman的請求截圖:

很明顯,這個請求中是有傳遞用戶名和密碼的,所以程序正常運行,返回如下結果:

我們的重點是要測試異常,所以把請求參數都去掉,什么都不傳,響應以下結果:

很明顯,code就是我們在枚舉中定義的code,msg就是在拋出異常的時候填寫的異常信息,隨后這個異常完美的被帶有@RestControllerAdvice注解的GlobalExceptionHandler類的baseServiceException方法所攔截,成功響應上面的結果。

OK,這就是springboot的異常處理與自定義異常的使用案例,這些都是十分基礎的東西,后面我會給大家分享一些技術干貨,請各位園友多多支持。

 

非淡泊無以明志,非寧靜無以致遠。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM