SpringBoot 工程中的異常處理方式

背景分析

在項目的開發中,無論是對底層的數據邏輯操做過程,仍是業務邏輯的處理過程,仍是控制邏輯的處理過程,都不可避免會遇到各類可預知的、不可預知的異常。處理好異常對系統有很好的保護做用,同時會大大提升用戶的體驗。web

異常處理分析

概述

Java項目中處理異常方式無非兩種,要麼執行trycatch操做,要麼執行throw操做(拋給其它對象處理),不管採用哪一種方式,其目的是讓咱們的系統對異常要有反饋。但如今的問題是咱們如何讓這種反饋代碼的編寫即簡單又直觀、友好。spring

處理規範

咱們在處理異常的過程當中一般要遵循必定的設計規範,例如:segmentfault

  • 捕獲異常時與拋出的異常必須徹底匹配,或者捕獲異常是拋出異常的父類類型。
  • 避免直接拋出RuntimeException,更不容許拋出Exception或者Throwable,應使用有業務含義的自定義異常(例如ServiceException)。
  • 捕獲異常後必須進行處理(例如記錄日誌)。若是不想處理它,須要將異常拋給它的調用者。
  • 最外層的邏輯必須處理異常,將其轉化成用戶能夠理解的內容。
  • 避免出現重複的代碼(Don’t Repeat Yourself),即DAY原則。

SpringBoot 工程下的異常處理

準備工做

第一步:建立項目或module,並添加web依賴,代碼以下:瀏覽器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

第二步:修改項目訪問端口爲80,例如springboot

server.port=80

第三步:定義Controller類,代碼以下:app

package com.cy.pj.arithmetic.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class ArithmeticController {

  @RequestMapping("doCompute/{n1}/{n2}")
  @ResponseBody
  public String doCompute(@PathVariable  Integer n1, 
  @PathVariable Integer n2){
          Integer result=n1/n2;
          return "Result is "+result;
  }
}

第四步啓動項目進行訪問測試框架

在瀏覽器地址欄輸入http://localhost/doCompute/10/2,檢測輸出結果。spring-boot

Result is 5

默認異常處理

在瀏覽器地址欄輸入http://localhost/doCompute/10/0,檢測輸出結果。測試

image.png

對於這樣的默認異常處理(spring boot提供),用戶體驗不太友好,爲了呈現更加友好的異常信息,咱們一般要對異常進行自定義處理。spa

本身try異常處理

在控制層方法中,咱們能夠進行try catch處理,例如:

@RequestMapping("doCompute/{n1}/{n2}")
  @ResponseBody
  public String doCompute(@PathVariable  Integer n1, 
  @PathVariable Integer n2){
          try{
          Integer result=n1/n2;
          return "Result is "+result;
          }catch(ArithmeticException e){
          return "exception is "+e.getMessage();
          }
  }

一個Controller類中一般會有多個方法,這樣多個方法中都寫try語句進行異常處理會帶來大量重複代碼的編寫,不易維護。

Controller內部定義異常處理方法

在Controller類中添加異常處理方法,代碼以下:

@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public String doHandleArithmeticException(ArithmeticException e){
    e.printStackTrace();
    return "計算過程當中出現了異常,異常信息爲"+e.getMessage();
}

@ExceptionHandler註解描述的方法爲異常處理方法(註解中的異常類型爲可處理的異常類型),假如Controller類中的邏輯方法中出現異常後沒有處理異常,則會查找Controller類中有沒有定義異常處理方法,假如定義了,且能夠處理拋出的異常類型,則由異常處理方法處理異常。

控制層中的全局異常處理類及方法定義

當項目由多個控制層類中有多個共性異常的處理方法定義時,咱們能夠將這些方法提取到公共的父類對象中,可是這種方式是一種強耦合的實現,不利於代碼的維護。咱們還能夠藉助spring框架中web模塊定義的全局異常處理規範進行實現,例如定義全局異常處理類,代碼以下:

package com.cy.pj.common.web;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ArithmeticException.class)
    public String doHandleArithmeticException(ArithmeticException e){
        e.printStackTrace();
        return  "計算過程當中出現了異常,異常信息爲"+e.getMessage();
    }
}

其中,@RestControllerAdvice 註解描述的類爲全局異常處理類,當控制層方法中的異常沒有本身捕獲,也沒有定義其內部的異常處理方法,底層默認會查找全局異常處理類,調用對應的異常處理方法進行異常處理。如圖所示:

image.png

總結(Summary)

本小節主要是對springboot中的異常處理機制進行了簡單分析和講解。目的是掌握springboot工程下的異常處理方式,並基於業務的不一樣進行響應的異常處理。從而有效提升其用戶體驗,增強系統的容錯能力。

springboot

相關文章
相關標籤/搜索