溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java項(xiàng)目中怎么處理異常

發(fā)布時(shí)間:2021-07-23 16:22:38 來源:億速云 閱讀:132 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關(guān)Java項(xiàng)目中怎么處理異常,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。


(一)概述

異常處理是一個(gè)系統(tǒng)最重要的環(huán)節(jié),當(dāng)一個(gè)項(xiàng)目變得很大的時(shí)候,異常處理和日志系統(tǒng)能讓你快速定位到問題。對于用戶或者接口調(diào)用者而言,優(yōu)雅的異常處理可以讓調(diào)用者快速知道問題所在。本文將介紹如何優(yōu)雅地處理異常。

(二)使用通用的返回體

我們希望所有的錯(cuò)誤都以Json的方式返回給客戶,因此拿出上次寫的通用返回體,新建一個(gè)類CommonResult記錄返回體。

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

新建一個(gè)枚舉類ResponseCode集成code和message。

public enum ResponseCode {

    // 系統(tǒng)模塊
    SUCCESS(0, "操作成功"),
    ERROR(1, "操作失敗"),
    SERVER_ERROR(500, "服務(wù)器異常"),

    // 通用模塊 1xxxx
    ILLEGAL_ARGUMENT(10000, "參數(shù)不合法"),
    REPETITIVE_OPERATION(10001, "請勿重復(fù)操作"),
    ACCESS_LIMIT(10002, "請求太頻繁, 請稍后再試"),
    MAIL_SEND_SUCCESS(10003, "郵件發(fā)送成功"),

    // 用戶模塊 2xxxx
    NEED_LOGIN(20001, "登錄失效"),
    USERNAME_OR_PASSWORD_EMPTY(20002, "用戶名或密碼不能為空"),
    USERNAME_OR_PASSWORD_WRONG(20003, "用戶名或密碼錯(cuò)誤"),
    USER_NOT_EXISTS(20004, "用戶不存在"),
    WRONG_PASSWORD(20005, "密碼錯(cuò)誤"),
    ;

    ResponseCode(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    private Integer code;
    private String msg;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

(三)自定義運(yùn)行時(shí)異常

自定義一個(gè)運(yùn)行時(shí)異常類,構(gòu)造方法傳入異常參數(shù)即可。

public class MyException extends RuntimeException{
    private String msg;

    public MyException(String msg) {
        super(msg);
    }
}

(四)編寫一個(gè)統(tǒng)一的異常處理類

異常處理類是整個(gè)異常處理核心,SpringBoot中提供了ControllerAdvice注解來攔截異常,使用RestControllerAdvice注解保證了返回Json格式。

如果攔截到的異常屬于MyException,則按Json格式返回錯(cuò)誤結(jié)果。

@RestControllerAdvice
public class ExceptionController {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = Exception.class)
    public CommonResult exceptionHandler(Exception e){
        //如果拋出的異常屬于自定義異常,就以JSON格式返回
        if (e instanceof MyException){
            return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"自定義的錯(cuò)誤為:"+e.getMessage());
        }
        //如果都不是就打印出異常的信息
        return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"錯(cuò)誤的信息為:"+e.getMessage());
    }
}

(五)測試

為了看初效果,這里手動(dòng)拋出一個(gè)異常來測試,新建IndexController,手動(dòng)拋出異常

@RestController
public class IndexController {

    @RequestMapping(value = "/index",method = RequestMethod.GET)
    public String index(){
        throw new MyException("測試");
    }
}

查看調(diào)用結(jié)果:

Java項(xiàng)目中怎么處理異常

(六)對實(shí)體類的校驗(yàn)

有這樣一個(gè)場景,登陸注冊時(shí)用戶名和密碼有長度限制,手機(jī)號(hào)有格式限制,如果不滿足要求就無法注冊。這個(gè)功能前端可以限制,但是對于后端接口而言,也需要進(jìn)行限制,萬一前端沒有限制住呢。

導(dǎo)入兩個(gè)校驗(yàn)依賴包:

<!--校驗(yàn)-->
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.0.Final</version>
</dependency>

編寫實(shí)體類,在每個(gè)屬性上加上校驗(yàn)包的驗(yàn)證參數(shù)。

@Data
public class Register {

    @Length(max = 20,min = 4,message = "用戶名長度需要在4到20個(gè)字符之間")
    @NotBlank(message = "用戶名不能為空")
    private String username;

    @NotBlank(message = "手機(jī)號(hào)不能為空")
    @Pattern(regexp = "^1[3|4|5|8][0-9]\\d{8}$",message = "電話號(hào)碼格式不正確")
    private String phone;

    @Length(max = 20,min = 4,message = "密碼長度需要在4到20個(gè)字符之間")
    @NotBlank(message = "密碼不能為空")
    private String password;
}

我們在需要使用的方法中增加@Valid注解進(jìn)行校驗(yàn),比如這個(gè)post請求中我要校驗(yàn)。

@PostMapping("/register")
public CommonResult register(@Valid @RequestBody Register register){
    //一連串注冊的業(yè)務(wù)
    userService.registerUser(register);
    return new CommonResult(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMsg(),"");
}

@Valid在校驗(yàn)失敗的情況下會(huì)報(bào)出參數(shù)不合法的異常,還是在統(tǒng)一的異常處理類中捕獲異常,如果是MethodArgumentNotValidException,就取出對應(yīng)的message數(shù)據(jù)。

@RestControllerAdvice
public class ExceptionController {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = Exception.class)
    public CommonResult exceptionHandler(Exception e){
        //如果屬于參數(shù)校驗(yàn)異常,就拋出校驗(yàn)的錯(cuò)誤
        if (e instanceof MethodArgumentNotValidException){
            MethodArgumentNotValidException methodArgumentNotValidException= (MethodArgumentNotValidException) e;
            return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),
                    "校驗(yàn)錯(cuò)誤:"+methodArgumentNotValidException.getBindingResult().getFieldError().getDefaultMessage());
        }//如果是自定義的異常,就給出具體的異常原因
        else if (e instanceof MyException){
            return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"自定義的錯(cuò)誤為:"+e.getMessage());
        }
        //如果都不是就打印出異常的信息
        return new CommonResult(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMsg(),"錯(cuò)誤的信息為:"+e.getMessage());
    }
}

(七)測試校驗(yàn)

接下來就可以測試校驗(yàn)的功能了,通過postman訪問

Java項(xiàng)目中怎么處理異常

如果輸入?yún)?shù)不滿足之前的設(shè)置,就會(huì)給出具體的錯(cuò)誤信息。而不是拋出讓人無法接收的報(bào)錯(cuò):

Java項(xiàng)目中怎么處理異常

以上就是Java項(xiàng)目中怎么處理異常,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI