數據的校驗和空指針
- 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,如果是一個對象,拿這個對象去操作,這個時候就可能產生空指針。
緩存存儲數據時,特別是過期數據,且更換頻繁的情況,就更應該去考慮在什麼情況下為空,為什麼為空。
在先了空指針判斷之後,更應該考慮為什麼去判斷,在什麼情況下才會出現。
三、總結
綜上所述就是得出結論:
-
==傳入的參數不可信任,需要對必傳參數做校驗,錯誤就提示用戶。==
-
==獲取到的數據也不可信任,需要對獲取數據做為空判斷。==