springmvc學習筆記--REST API的異常處理

 

前言:
  最近使用springmvc寫了很多rest api, 以爲真是一個好框架. 以前描述的幾篇關於rest api的文章, 其實仍是不夠完善. 好比當遇到參數缺失, 類型不匹配的狀況時, 直接拋出異常, 返回的內容是400+的錯誤頁面, 而不是json內容, 這讓移動端的調用方很難處理.
  本文主要講述對於rest api, springmvc對異常的解決處理方案.html

系列整理:
  springmvc學習筆記系列的文章目錄:
  • idea建立springmvc項目
  • 面向移動端的REST API
  • Jackson的使用和定製
  REST API的設計原則博文
  • 移動互聯網實戰—Web Restful API設計和基礎架構java

場景構造:
  大背景, 咱們已藉助使用Jackson框架和註解@ResonseBody來實現pojo對象以json形式返回.
  先來構造幾個案例, 來描述咱們所要解決的問題.
  共同的測試代碼:spring

@Controller
@RequestMapping("/math")
public class TestController {

    @RequestMapping(value="/div", method= RequestMethod.GET)
    @ResponseBody
    public int div(@RequestParam("a") int a,
                    @RequestParam("b") int b) {
        // *) div zero error
        return a / b;
    }

}

  1). 場景一(參數缺失, 類型不匹配)
  case 1:
    http://localhost:8080/math/div?a=10
  參數b缺失, 返回400錯誤頁
  
  case 2:
    http://localhost:8080/math/div?a=10&b=hehe
  參數b類型不對, 類型轉換失敗
  
  咱們的但願是, 將這些參數缺乏/類型不匹配的異常, 以JSON串的形式返回, 而不是以400的錯誤頁面返回.
  2). 場景二(業務代碼拋出異常)
  case 1:
    http://localhost:8080/math/div/a=10&b=0
  發生除零異常
  
  內部拋出業務異常很是常見, 防不勝防, 返回是500+的錯誤頁面.json

解決方案:
  基於上文的場景, 遇到異常時, 返回的都是400+/500+的錯誤頁面, 一方面客戶端sdk解析和處理麻煩, 另外一方面泄露了內部的錯誤細節. 那是否一種辦法攔截異常, 並返回本身定義的錯誤數據格式呢?
  答案是確定的, springmvc引入了織入@ControlAdvice.
  其對異常的處理, 很是的方便, 可簡單參考以下sample.api

@ControllerAdvice
public class RestApiControlAdvice {

	@ExceptionHandler(value=RuntimeException.class)
	@ResponseBody
	public String handle(RuntimeException e) {
		// *記入異常日誌
		return e.getMessage();
	}

	@ExceptionHandler(value=Exception.class)
	@ResponseBody
	public String handle(Exception e) {
		// *記入異常日誌
		return e.getMessage();

	}

}

  經過結合註解@ExceptionHanlder, 來定義具體的異常處理, 以及返回的結果.
  這邊須要注意的是, @ExceptionHandler可定義多個, 當多個匹配時, 按編寫最先的處理函數優先處理. 這邊就像try/catch那種常見的狀況了, 既順序敏感. 最佳實踐, 須要把處於頂層的異常類擱置到代碼最尾端.
  固然對於參數缺失/類型不匹配的處理, 能夠以下定義.微信

@ExceptionHandler(value=MissingServletRequestParameterException.class)
@ResponseBody
public TResult<Void> handle(MissingServletRequestParameterException e) {
	return "Miss parameter " + e.getParameterName() + ":" + e.getParameterType();
}

@ExceptionHandler(value= TypeMismatchException.class)
@ResponseBody
public String handle(TypeMismatchException e) {
	return e.getErrorCode() + ", required type: " + e.getRequiredType() + ", but value: " + e.getValue();
}

  業務上的異常代碼, 每每能夠抽象出一個異常基類.架構

總結:
  springmvc的入門和上手確實很是快, 但要真正的理解. 確實仍是須要花功夫, 這邊只是簡單介紹一下, 並無深刻源碼. 但願未來有一天有機會講講背後的技術原理.mvc

公衆號&遊戲站點:
  我的微信公衆號: 木目的H5遊戲世界
  
  我的遊戲做品集站點,
 www.mmxfgame.com 請點擊訪問http://120.26.221.54/.  
app

相關文章
相關標籤/搜索