數據的校驗和空指針

  • 2019 年 10 月 13 日
  • 筆記

一、重視數據的校驗

為什麼要重視校驗,因為對於外面傳輸的數據,程序是並不知道具體值的,一些邊界之外的值就可能導致程序異常,一般情況下會注意,但是更多的時候等到程序在測試環境中出現了錯誤,才會去校驗,這種情況屬於被動校驗,程序員更應該是主動校驗數據。

public void login(LoginForm form,HttpServeletRequest request){      //直接處理業務邏輯      userService.login(form);  }

上訴這種情況就要求了調用該接口的必須要傳入正確參數,但是對於調用這多且複製時,傳入的參數可能就出現空的情況,如果沒有檢查,那麼就報空指針。程序員是不允許上線的程序出現空指針異常,要將空指針異常視為一個嚴重的問題,而不是簡簡單單的BUG問題。

public void login(LoginForm form,HttpServeletRequest request){      if(form.getAccount == null || "".equals(form.getAccount))){          //錯誤處理          return;      }      //直接處理業務邏輯      userService.login(form);  }

上述就避免了後續比較數據出現異常。

上述是一個空指針異常,而插入到數據庫中的數據會有一個邊界值,如account在數據庫中最大長度為20,如果傳入的數據超過,那麼該條數據插入不到數據庫中,直接異常,如果還沒有異常處理時,直接返回錯誤的情況,那麼就讓人認為水平有問題了。

上述處理有些複雜,那麼可以使用框架hibernate validator框架,框架能夠滿足我們大部分情況

@GET  @SET  public class LoginForm{        @NotBlank(message="賬號不能為空")      private String account;        @NotBlank(message="密碼不能為空")      private String pwd;  }      public void login(@Valid LoginForm form,HttpServeletRequest request){      //直接處理業務邏輯      userService.login(form);  }

二、不為空判斷

在很多情況,我們都會認為有值,但是程序有些情況不是按照自己的來

public void login(LoginForm form ){  User user = userDao.select(form.getAccount());      if(!form.getPwd().equals(user.getPwd())){          //判斷密碼錯誤邏輯處理      }  }

上述代碼中用戶不存在時,就會出現空指針異常。為什麼會出現空指針,用戶登錄的時候,傳入正確的賬戶,數據庫中肯定是有值的,但是用戶就是傳入一個異常的賬戶,獲取到的User就是等於null,出現了空指針異常。即使用戶輸入正確的賬戶,但如果有其他業務邏輯刪除該賬戶,或者該賬戶凍結,而查詢是非凍結的賬戶,那麼還是查詢為空,後續還是出現異常。

這種就需要判斷user是否為空,做為空處理,然後在處理密碼是否匹配。

思考在什麼情況下為空,上述判斷是不為空應該做業務邏輯,還有一些情況是一般情況下一直存在,但是因為特殊原因出現問題,比如從緩存中去數據
String value = redis.get(key);
redis的有一個最大內存,且有一個策略去刪除內存滿了之後的操作,而剛好,如果該數據已經被刪除了,那獲取到的值是null,如果是一個對象,拿這個對象去操作,這個時候就可能產生空指針。

緩存存儲數據時,特別是過期數據,且更換頻繁的情況,就更應該去考慮在什麼情況下為空,為什麼為空。

在先了空指針判斷之後,更應該考慮為什麼去判斷,在什麼情況下才會出現。

三、總結

綜上所述就是得出結論:

  1. ==傳入的參數不可信任,需要對必傳參數做校驗,錯誤就提示用戶。==

  2. ==獲取到的數據也不可信任,需要對獲取數據做為空判斷。==