JavaEE進階知識學習-----SpringBootWeb進階-8-異常處理知識

SpringBoot中對異常的統一處理

異常處理也可以說成是一種數據傳輸方式,簡單來講,可以在Services中拋出異常信息,在controller中接收異常信息,然后就可以返回到頁面顯示了。

異常處理實例

如果我們需要獲取用戶的年齡,并根據年齡進行判斷,并作出不同的響應。

1.首先我們會定義返回結果數據的通用類,如下:
public class Msg {

    //狀態碼100-成功,200-失敗
    private int code;
    //提示信息
    private String msg;
    //具體提示消息
    private String message;
    //用戶要返回給瀏覽器的數據
    private Map<String, Object> extend = new HashMap<String, Object>();

    public static Msg success(String message){
        Msg result = new Msg();
        result.setCode(100);
        result.setMsg("處理成功");
        return result;
    }
    public static Msg fail(String message){
        Msg result = new Msg();
        result.setCode(200);
        result.setMsg("處理失敗");
        result.setMessage(message);
        return result;
    }
    public Msg add(String key,Object value){
        this.getExtend().put(key, value);
        return this;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }

    public String getMessage() {
        return message;
    }

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

    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Map<String, Object> getExtend() {
        return extend;
    }
    public void setExtend(Map<String, Object> extend) {
        this.extend = extend;
    }
}
2.修改Controller中的添加一個用戶的方法
@PostMapping(value = "/users")
public Msg addUser(@Valid User user, BindingResult bindingResult){
    if(bindingResult.hasErrors()){
        return Msg.fail(bindingResult.getFieldError().getDefaultMessage());
    }
    user.setUserName(user.getUserName());
    user.setAge(user.getAge());
    return Msg.success().add("user",userRepository.save(user));
}
3.測試

我們先測試失敗的時候,我們開始做了一個年齡age的檢驗,不滿足校驗就會報錯,如下:

image

我們再來測試成功的時候,如下:

image

可以看出我們寫的通用的返回類,返回給客戶端的數據格式是一致的。上面僅僅是測試一下我們寫的通用返回類,下面我們將繼續完成對用戶年齡的判斷。

4.Services中添加方法
public void getAge(Integer id){
    User user = userRepository.findOne(id);
    Integer age = user.getAge();
    if(age < 20){
        //返回你還在上大學吧
    }else if(age > 20 && age < 30){
        //返回你剛工作不久吧
    }
}
5.userController中根據年齡獲取用戶
@GetMapping(value = "users/getAge/{id}")
public void getAge(@PathVariable("id") Integer id){
    userService.getAge(id);
}

但是,在controller中怎么獲取Services中的返回的值,可能有的或說將Services的返回值改為String,如果我們要做其他操作,要返回一個對象或者其他呢,當然還有很多方式可以實現,但是隨著業務的復雜,我們最好的使用統一異常的方式較為好些。

6.修改Services中的getAge方法
public void getAge(Integer id) throws Exception{
    User user = userRepository.findOne(id);
    Integer age = user.getAge();
    if(age < 20){
        //返回你還在上大學吧
        throw new Exception("你還在上大學吧!!!");
    }else if(age > 20 && age < 30){
        //返回你剛工作不久吧
        throw new Exception("你剛工作不久吧!!!");
    }
}
7.增加一個統一異常處理類
import com.study.springbootdemo.domain.Msg;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class ExceptionHandle {

    //使用注解說明要捕獲哪一個異常類,Exception是我們拋出異常使用的類
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Msg handle(Exception e){
        return Msg.fail(e.getMessage());
    }
}
8.測試

首先先看我數據庫中表的信息


image

測試年齡小于20d的異常捕獲和返回


image

測試年齡大于20小于30的異常捕獲和返回
image
9.自定義異常類

使用Exception異常類只能拋出一個異常信息,throw new Exception("你還在上大學吧!!!");,如果我們要拋出其他的信息就要自定義異常類。

public class UserException extends RuntimeException{

    private String mes;

    public UserException(String msg,String message){
        super(message);
        this.mes = msg;
    }

    public String getMes() {
        return mes;
    }

    public void setMes(String mes) {
        this.mes = mes;
    }
}
10.修改Services類,拋出自定義異常類
public void getAge(Integer id) throws Exception{
    User user = userRepository.findOne(id);
    Integer age = user.getAge();
    if(age < 20){
        //返回你還在上大學吧
        throw new UserException("年齡小于20的異常","你還在上大學吧!!!");
    }else if(age > 20 && age < 30){
        //返回你剛工作不久吧
        throw new UserException("年齡大于20且小于30的異常","你剛工作不久吧!!!");
    }
}
11.異常捕獲類
@ControllerAdvice
public class ExceptionHandle {

    //使用注解說明要捕獲哪一個異常類,Exception是我們拋出異常使用的類
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Msg handle(Exception e){
        if(e instanceof UserException){
            UserException userException = (UserException) e;
            userException.getMes();//自定義異常的第一個信息
            userException.getMessage();//自定義異常的第二個信息

            return Msg.fail(userException.getMes());
        }
        return Msg.fail(e.getMessage());
    }
}
12優化Services

如果有很多的異常信息在各個類中拋出,修改和維護就特別困難,所以我們使用枚舉來統一管理,新建一個枚舉

public enum ResultEnum {
    ERROR_ONE("101","你還在上大學吧!!!"),
    ERRON_TWO("102","你剛工作不久吧!!!")
    ;
    private String mes;
    private String message;

    public String getMes() {
        return mes;
    }
    ResultEnum(String msg,String message){
        this.mes = msg;
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
}

然后修改我們自定義異常類

public class UserException extends RuntimeException{

    private String mes;

    public UserException(ResultEnum resultEnum){
        super(resultEnum.getMessage());
        this.mes = mes;
    }

    public String getMes() {
        return mes;
    }

    public void setMes(String mes) {
        this.mes = mes;
    }
}

修改我們的Services

public void getAge(Integer id) throws Exception{
    User user = userRepository.findOne(id);
    Integer age = user.getAge();
    if(age < 20){
        //返回你還在上大學吧
        throw new UserException(ResultEnum.ERROR_ONE);
    }else if(age > 20 && age < 30){
        //返回你剛工作不久吧
        throw new UserException(ResultEnum.ERRON_TWO);
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容