最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中的異常處理與參數(shù)校驗的方法實現(xiàn)

 更新時間:2020年04月21日 16:16:32   作者:一個程序員的成長  
這篇文章主要介紹了SpringBoot中的異常處理與參數(shù)校驗的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

兄弟們好,這次來跟老鐵交流兩個問題,異常和參數(shù)校驗,在說參數(shù)校驗之前我們先來說異常處理吧,因為后面參數(shù)的校驗會牽扯到異常處理這塊的內(nèi)容。

異常處理

說到異常處理,我不知道大家有沒有寫過或者遇到過如下的寫法。

public void saveUser() {
    
  try {
    // 所有的業(yè)務(wù)內(nèi)容,目測幾百行
  }catch (Exception e) {
    e.printStackTrace();
  }
}

如果出現(xiàn)上述的代碼,里面包含了大量的業(yè)務(wù)代碼,如果是你寫的,趕緊改掉,不是你寫的找寫的,吐槽趕緊改掉。

存在的問題:

1、會遇到性能瓶頸;
2、很難定位問題;
3、try嵌套過多可讀性很差;

不管什么原因出現(xiàn)了上述代碼,那么最好還是改一下,如果非要在業(yè)務(wù)代碼中try,那么也應(yīng)該只在可能出現(xiàn)異常的地方使用try,而不是try整個業(yè)務(wù)代碼。

SpringBoot中的異常捕獲

直接上代碼

@RestControllerAdvice
public class GlobalException {

  @ExceptionHandler(value = Exception.class) // 捕獲的異常類型
  public Object globalException(Exception ex) {

    // 異常處理
    ex.printStackTrace();

    return "出現(xiàn)異常";
  }
}

那么在SpringBoot中我們就可以通過這樣的一個配置可以獲取到項目中出現(xiàn)異常的地方,我們可以在這個方法中可以獲取出現(xiàn)異常的類的詳細(xì)信息,那么是不是所有的異常我們?nèi)渴褂肊xception來處理呢?那么肯定是不合適的。
我們模擬一個by zero的異常,然后再配置一個處理ArithmeticException異常的處理器,代碼如下:

@RestControllerAdvice
public class GlobalException {


  @ExceptionHandler(value = Exception.class) // 捕獲的異常類型
  public Object globalException(Exception ex) {

    ex.printStackTrace();

    return "出現(xiàn)異常";
  }

  @ExceptionHandler(value = ArithmeticException.class)
  public Object arithmeticException(ArithmeticException ex) {

    ex.printStackTrace();
    return "by zero異常";
  }
}

如果這個時候出現(xiàn)by zero異常,走ArithmeticException異常處理,原因就是因為如果有更小范圍的異常處理類,那么會走小范圍的異常處理器。不會走globalException更大的異常處理類。

這樣處理之后,我們就不需要在項目中去寫那么多的try了,是不是方便了很多。

除了使用這些已經(jīng)存在的異常外,其實我們還可以自定義我們的異常,比如我們常用的用戶未登錄異常、參數(shù)錯誤異常等等。但是考慮到這篇文章的篇幅問題,這次就先不寫了,有興趣的朋友可以直接下面留言,人多了我盡快更新。

注意坑:

這里跟大家分享一個踩過的坑,不能再Filter過濾器中拋出異常,如果通過在過濾器中拋出異常,然后通過異常處理類來處理,那么是不可能的,因為處理器是捕獲不到Filter拋出的異常的。

參數(shù)校驗

老規(guī)矩,先來看一段代碼

@RequestMapping(value = "/save/user")
public Object saveUser(UserPO userPO) {

  if (userPO.getAge() == null) {
    return "請求參數(shù)錯誤";
  }

  if (userPO.getSex() == null) {
    return "請求參數(shù)錯誤";
  }
  if (userPO.getUsername() == null) {
    return "請求參數(shù)錯誤";
  }

  // ...

  return "SUCCESS";
}

應(yīng)該見過這種校驗參數(shù)的吧,說實話我寫過。越寫感覺越low,所以狠心一下,還是趁早改吧。

@Validated注解

這個注解其實是Spring提供的,如果你的項目不是SpringBoot項目,需要引一下需要的pom文件,如果是,那么就不用管了,SpringBoot已經(jīng)幫我們引入了。

網(wǎng)上看了好多的博客,許多都說的不是很全,大部分都是說JavaBean參數(shù)的校驗,但是我們項目中有些接口可能就涉及一個參數(shù),根本不需要寫一個JavaBean,對于單一參數(shù)的校驗好多博客還是沒說的,那么我們這次就一次性講清楚。

單一參數(shù)的校驗

直接看代碼吧

@Validated
@RestController
public class BookController {
  
  @RequestMapping(value = "/book/info", method = RequestMethod.GET)
  public Object getBookInfo(@NotBlank(message = "書籍ID不能為空") String bookId) {

    return "SUCCESS";
  }
}

這里要跟大家特別說明下,如果是單一參數(shù)的校驗,那么我們必須要在類上面添加@Validated注解,不然我們整個單個參數(shù)校驗是不會生效的,可以看到我們在校驗參數(shù)bookId的時候,使用了@NotBlank那么顧名思義,就是這個參數(shù)不能為null,在調(diào)用了trim()方法之后也不能是空字符。

如果參數(shù)不滿足要求,那么會拋出ConstraintViolationException異常,這個異常只有在單一參數(shù)校驗的時候拋出,如果你的參數(shù)是JavaBean,那么就不是這個異常了。

既然我們知道了它會拋出異常,并且我們也知道是什么異常類型,那么久超級簡單了,我們可以直接使用上面剛學(xué)的異常處理類來處理我們的異常。

我找個里面寫的比較簡單,如果你想寫的復(fù)雜一點,其實也是可以的,但是作為后端來說,我覺得沒必要,因為我們不能給前端提示太過明顯的錯誤提示,防止別人惡意攻擊我們,就像用戶名密碼錯誤,不能明確的告訴用戶到底是用戶名錯誤還是密碼錯誤,只能提示用戶名或密碼錯誤。

如果大家非要把詳細(xì)的錯誤信息打出來,要看到到底是哪個參數(shù)校驗不通過,也可以通過下面的方式將具體的參數(shù)錯誤信息打印出來。輸出的錯誤結(jié)果其實就是上面message里面的內(nèi)容。

@RestControllerAdvice
public class ExceptionCatch {
  /**
   * 單個參數(shù)異常處理
   *
   * @param ex
   * @return
   */
  @ExceptionHandler(value = ConstraintViolationException.class)
  public Object constraintViolationException(ConstraintViolationException ex) {

    // 獲取具體的錯誤信息
    Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
    // 打印數(shù)據(jù)
    violations.forEach(e -> System.out.println(e.getMessage()));
    
    return "單個-請求參數(shù)錯誤";
  }
}

JavaBean參數(shù)校驗(form-data)

JavaBean的寫法

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserPO {

  @NotBlank(message = "用戶名不能為空")
  private String username;

  @NotNull(message = "年齡不能為空")
  @Min(value = 1, message = "年齡最小為1")
  @Max(value = 200, message = "年齡最大為200")
  private Integer age;

  @NotBlank(message = "性別不能為空")
  private String sex;
}

Controller寫法

@RequestMapping(value = "/save/user")
public Object saveUser(@Validated UserPO userPO) {

  // ...

  return "SUCCESS";
}

跟單一參數(shù)校驗不一樣的是JavaBean的校驗方式需要將@Validated寫在方法參數(shù),而不是類上。如果出現(xiàn)了參數(shù)校驗不通過,同樣的也會拋出一個異常,BindException。

/**
 * 一般參數(shù)校驗綁定異常處理
 *
 * @param ex
 * @return
 */
@ExceptionHandler(value = BindException.class)
public Object bindException(BindException ex) {

  BindingResult bindingResult = ex.getBindingResult();

  // 獲取所有的錯誤信息
  List<ObjectError> allErrors = bindingResult.getAllErrors();

  // 輸出
  allErrors.forEach(e -> System.out.println(e.getDefaultMessage()));

  return "請求參數(shù)錯誤";
}

注意:大家要注意post請求有兩種方式,一種是基于form-data格式的數(shù)據(jù)傳遞,另外一種就是基于json格式的數(shù)據(jù)傳遞,兩種傳遞方式引發(fā)的異常也是不一樣的,所以我們還要單獨處理基于json的參數(shù)校驗異常處理。

JavaBean參數(shù)校驗(json)

我們先來看下Controller接收方式

@RequestMapping(value = "/save/user")
public Object saveUser(@Validated @RequestBody UserPO userPO) {

  // ...

  return "SUCCESS";
}

對應(yīng)的參數(shù)異常處理

/**
 * JSON參數(shù)校驗綁定異常處理
 *
 * @param ex
 * @return
 */
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Object methodArgumentNotValidException(MethodArgumentNotValidException ex) {

  BindingResult bindingResult = ex.getBindingResult();

  // 獲取所有的錯誤信息
  List<ObjectError> allErrors = bindingResult.getAllErrors();

  // 輸出
  allErrors.forEach(e -> System.out.println(e.getDefaultMessage()));

  return "請求參數(shù)錯誤-json";
}

最后的話

那么到這里,我們本篇文章就結(jié)束了,主要介紹了兩部分內(nèi)容,異常的處理和參數(shù)的校驗。雖然很簡單,但是我個人感覺還是挺常用的技能。所以與大家進行分享,如果對你有點幫助,就來點個贊吧。如果有什么不明白的也歡迎下方留言,一起來交流。

到此這篇關(guān)于SpringBoot中的異常處理與參數(shù)校驗的方法實現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot 異常處理與參數(shù)校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JVM參數(shù)NativeMemoryTracking的使用

    JVM參數(shù)NativeMemoryTracking的使用

    本文主要介紹了JVM參數(shù)NativeMemoryTracking的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • Java實現(xiàn)XML與JSON的互相轉(zhuǎn)換詳解

    Java實現(xiàn)XML與JSON的互相轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實現(xiàn)XML與JSON的互相轉(zhuǎn)換,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • 使用SpringMVC在redirect重定向的時候攜帶參數(shù)的問題

    使用SpringMVC在redirect重定向的時候攜帶參數(shù)的問題

    這篇文章主要介紹了使用SpringMVC在redirect重定向的時候攜帶參數(shù)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 談?wù)凧ava中對象,類和this,super,static關(guān)鍵字的使用

    談?wù)凧ava中對象,類和this,super,static關(guān)鍵字的使用

    對象:對象是類的一個實例,有狀態(tài)和行為。類:類是一個模板,它描述一類對象的行為和狀態(tài)。本文就來和大家聊聊Java中對象,類和關(guān)鍵字的使用,需要的可以參考一下
    2022-08-08
  • IDEA在一個項目空間下管理多個項目的操作方法

    IDEA在一個項目空間下管理多個項目的操作方法

    這篇文章主要介紹了IDEA如何在一個項目空間下管理多個項目,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • 利用Socket.io 實現(xiàn)消息實時推送功能

    利用Socket.io 實現(xiàn)消息實時推送功能

    這篇文章主要介紹了利用Socket.io 實現(xiàn)消息實時推送功能,需要的朋友可以參考下
    2017-12-12
  • java實現(xiàn)Rabbitmq延遲隊列和惰性隊列

    java實現(xiàn)Rabbitmq延遲隊列和惰性隊列

    本文主要介紹了java實現(xiàn)Rabbitmq延遲隊列和惰性隊列,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • 基于Java的Scoket編程

    基于Java的Scoket編程

    本文詳細(xì)講解了基于Java的Scoket編程,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • Dubbo?LoadBalance基于權(quán)重的隨機負(fù)載均衡算法提高服務(wù)性能

    Dubbo?LoadBalance基于權(quán)重的隨機負(fù)載均衡算法提高服務(wù)性能

    這篇文章主要為大家介紹了Dubbo?LoadBalance基于權(quán)重的隨機負(fù)載均衡算法提高服務(wù)性能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪<BR>
    2023-10-10
  • springboot請求找不到路徑異常的問題

    springboot請求找不到路徑異常的問題

    這篇文章主要介紹了springboot請求找不到路徑異常的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論

饶平县| 台中市| 衡山县| 苍山县| 维西| 吴忠市| 冕宁县| 台北市| 平顺县| 北辰区| 阜新市| 含山县| 高陵县| 乌苏市| 蛟河市| 玛沁县| 浦北县| 玉环县| 朝阳县| 大新县| 综艺| 谷城县| 双鸭山市| 城口县| 唐山市| 金华市| 延长县| 莒南县| 当雄县| 仪征市| 东方市| 巴楚县| 莒南县| 武义县| 耿马| 隆林| 翁牛特旗| 博兴县| 揭阳市| 张掖市| 商城县|