天天看點

【學習筆記】springboot中的全局異常處理 和@ControllerAdvice的使用全局異常處理@ControllerAdvice的其他使用場景

文章目錄

  • 全局異常處理
    • 例子
  • @ControllerAdvice的其他使用場景

全局異常處理

系統中異常包括:編譯時異常和運作時異常RuntimeException ,前者通過捕獲異常進而擷取異常資訊,後者主要通過規範代碼開發、測試通過手段減少運作時異常的發生。在開發中,不管是dao層、service層還是controller層,都有可能抛出異常,在Springmvc中,能将所有類型的異常處理從各處理過程解耦出來,既保證了相關處理過程的功能較單一,也實作了異常資訊的統一處理和維護。

SpringBoot全局異常處理方式主要兩種:

使用@ControllerAdvice 和@ExceptionHandler 注解。

使用ErrorController類來實作

差別:

  1. @ControllerAdvice 方式隻能處理控制器抛出的異常。此時請求已經進入控制器中。
  2. ErrorController類方式可以處理所有的異常,包括未進入控制器的錯誤,比如404,401等錯誤
  3. 如果應用中兩者共同存在,則@ControllerAdvice 方式處理控制器抛出的異常,ErrorController類方式處理未進入控制器的異常。
  4. @ControllerAdvice 方式可以定義多個攔截方法,攔截不同的異常類,并且可以擷取抛出的異常資訊,自由度更大。

例子

GlobalException.java

例一

import com.xxxx.yebserver.pojo.RespBean;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* 全局異常
*
* @author zhoubin
* @since 1.0.0
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(SQLException.class)
public RespBean mySQLException(SQLException e) {
if (e instanceof SQLIntegrityConstraintViolationException) {
return RespBean.error("(唯一的鍵值重複了,)操作失敗!");
}
return RespBean.error("資料庫異常,操作失敗!");
}
}

           

@ControllerAdvice :表示這是一個控制器增強類,當控制器發生異常且符合類中定義的攔截異常類,将會被攔截

@ExceptionHandler :定義攔截的異常類

例二:

@ControllerAdvice
public class MyGlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView customException(Exception e) {
ModelAndView mv = new ModelAndView();
mv.addObject("message", e.getMessage());
mv.setViewName("myerror");
return mv;
}
}
           

在該類中,可以定義多個方法,不同的方法處理不同的異常,例如專門處理空指針的方法、專門處理數組越界的方法…,也可以直接向上面代碼一樣,在一個方法中處理所有的異常資訊。

@ExceptionHandler 注解用來指明異常的處理類型,即如果這裡指定為 NullpointerException,則數組越界異常不會進到這個方法來。

@ControllerAdvice的其他使用場景

全局資料綁定功能可以用來做一些初始化的資料操作,我們可以将一些公共的資料定義在添加了@ControllerAdvice 注解的類中,這樣,在每一個 Controller 的接口中,就都能夠通路導緻這些資料。

@ControllerAdvice
public class MyGlobalExceptionHandler {
@ModelAttribute(name = "md")
public Map<String,Object> mydata() {
HashMap<String, Object> map = new HashMap<>();
map.put("age", 99);
map.put("gender", "男");
return map;
}
}
           

使用 @ModelAttribute 注解标記該方法的傳回資料是一個全局資料,預設情況下,這個全局資料的 key就是傳回的變量名,value 就是方法傳回值,當然開發者可以通過@ModelAttribute 注解的 name 屬性去重新指定 key。

定義完成後,在任何一個Controller 的接口中,都可以擷取到這裡定義的資料:

@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(Model model) {
Map<String, Object> map = model.asMap();
System.out.println(map);
int i = 1 / 0;
return "hello controller advice";
}
}