探索guava(一)——前置條件Preconditions類


作用

可以簡潔的完成參數檢驗,在進行業務邏輯代碼前進行前置判斷。並且避免了冗長的if語句。guava將所有檢驗的API都放置於Preconditions類中

API

Preconditions類大致分為6種提供參數檢驗的方法,每種方法都有三個重載方法。重載方法的參數意義是:

  • 僅有待校驗的參數:拋出的異常中沒有錯誤消息;
  • 有一個Object對象作為額外參數:拋出的異常使用Object.toString() 作為錯誤消息;
  • *有一個String對象作為額外參數,還有一個Object[]參數,這兩個參數也是適用於異常錯誤消息的,處理的方式類似於String.format將Object的參數按順序替換掉String中的占位符(如%s)
  • 方法聲明(不包括額外參數) 描述 檢查失敗時拋出的異常
    checkArgument(boolean) 檢查boolean是否為true,用來檢查傳遞給方法的參數。 IllegalArgumentException
    checkNotNull(T) 檢查value是否為null,該方法直接返回value,因此可以內嵌使用checkNotNull。。 NullPointerException
    checkState(boolean) 用來檢查對象的某些狀態。 IllegalStateException
    checkElementIndex(int index, int size) 檢查index作為索引值對某個列表、字符串或數組是否有效。index>=0 && index<size *。 IndexOutOfBoundsException
    checkPositionIndex(int index, int size) 檢查index作為位置值對某個列表、字符串或數組是否有效。index>=0 && index<=size *。 IndexOutOfBoundsException
    checkPositionIndexes(int start, int end, int size) 檢查[start, end]表示的位置范圍對某個列表、字符串或數組是否有效* IndexOutOfBoundsException

實例

如:我們在做登錄操作的方法中,在未用前置條件前,代碼可能會如下:

 1 public User login(String userName,String password){
 2     if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)){
 3         throw new RuntimeException("用戶名或密碼不能為空");
 4     }
 5     User user = userService.queryUserByUserNameAndPassword(userName,password);
 6     if(null == user){
 7         throw new RuntimeException("用戶名或密碼錯誤");
 8     }
 9     //…………………………………………省略業務邏輯…………………………………………
10 }

當使用了Preconditions類后

public User login(String userName,String password){
       Preconditions.checkArgument(!(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)),"用戶名或密碼不能為空");
       User user = userService.queryUserByUserNameAndPassword(userName,password);
       Preconditions.checkNotNull(user,"用戶名或密碼錯誤");
       //…………………………………………省略業務邏輯…………………………………………
}

 

思考

相信大家也發現了,Preconditions類與Assert斷言類的思想基本是一致的,通過這個思想,我們也可以實現屬於自己的斷言類從而提升自己的開發效率。

假設一個場景,我們是基於接口開發工作的,接口通過JSON傳遞數據給前端。此時我們先定義一個JSON的結構。

public class ResponseEntity<T> implements Entity<T>,Serializable{

    private static final long serialVersionUID = 1L;

    //數據實體
    private T data;
    
    //結果碼
    private Integer code;
    
    //錯誤描述
    private String message;
    
    //…………
}

自定義一個異常類

public class GlobException extends RuntimeException{

    private static final long serialVersionUID = 1L;

    private String message;
    
    private Integer code;
}

定義自己的前置條件類(斷言類)

/**
 * 斷言類
 * @author cjl
 */
public abstract class Assert {

    /**
     * 斷言對象不為空,若對象為空則報異常
     * @param obj 待校驗對象
     * @param message 異常信息
     */
    public static void notNull(Object obj,String message){
        if(obj == null)
            throw new GlobException(message);
    }
    
    /**
     * 斷言對象不為空,若對象為空則報異常
     * @param obj 待校驗對象
     */
    public static void notNull(Object obj){
        Assert.notNull(obj, "The Object can't null");
    }
    
    /**
     * 斷言數字不能為零,若數字為零則報異常
     * @param num 待校驗數字
     * @param message 異常信息
     */
    public static void notZero(Integer num,String message){
        Assert.notNull(num);
        if(num.intValue() == 0)
            throw new GlobException(message);
    }
    
    /**
     * 斷言數字不能為零,若數字為零則報異常
     * @param num 待校驗數字
     */
    public static void notZero(Integer num){
        Assert.notZero(num,"The number can't equals zero");
    }
    
    /**
     * 斷言字符串不能為空,若字符串為空則報異常
     * @param string 待校驗字符串
     * @param message 異常信息
     */
    public static void notEmpty(String string,String message){
        if(StringUtils.isEmpty(string))
            throw new GlobException(message);
    }
    
    /**
     * 斷言字符串不能為空,若字符串為空則報異常
     * @param string 待校驗字符串
     */
    public static void notEmpty(String string){
        Assert.notEmpty(string,"The string can't empty");
    }
    
    /**
     * 斷言該布爾值為true,若為false則拋異常
     * @param expression 待校驗布爾值
     * @param message  異常信息
     */
    public static void isTrue(boolean expression,String message){
        if(!expression)
            throw new GlobException(message);
    }
    
    /**
     * 斷言該布爾值為true,若為false則拋異常
     * @param expression 待校驗布爾值
     */
    public static void isTrue(boolean expression){
        Assert.isTrue(expression,"The expression not true");
    }
}

這時候在定義一個全局異常處理類,這里使用的是Spring Mvc的@ControllerAdvice注解

**
 * 全局異常處理
 * @author cjl
 */
@ControllerAdvice
public class ExceptionHandlers {

    @SuppressWarnings("rawtypes")
    @ResponseBody
    @ExceptionHandler(GlobException.class)
    public ResponseEntity<?> exceptionHandler(GlobException exception){
        outException(exception);
        return new ResponseEntity(exception);
    }

    /**
     * 異常輸出
     * @param exception
     */
    private void outException(GlobException exception) {
        String content = String.format("****************系統發生異常(%s)************************", exception.getMessage());
        System.out.println(content);
    }
    
}

和上面的例子一樣,我們現在實現一個完成登錄的接口。

@RequestMapping("/login")
    public ResponseEntity<?> login(String userName,String password){
        Assert.isTrue(!(StringUtils.isEmpty(userName)||StringUtils.isEmpty(password)),"用戶名或密碼不能為空");
        User user = userService.queryByUserNameAndPassword(userName, password);
        Assert.notNull(user,"用戶名或密碼錯誤");
        return ResponseEntity.success(user);
}

 

現在我們傳用戶名和密碼,其中賬號為空:

接下來傳錯誤的用戶名和密碼 

正確的賬號密碼,完成登錄


免責聲明!

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



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