在Springboot或者Springcloud開發中爲了統一處理業務異常,需要自定義全局異常處理類統一處理業務異常。在spring 3.2中,新增了@ControllerAdvice 註解,可以用於定義@ExceptionHandler、@InitBinder、@ModelAttribute,並應用到所有@RequestMapping註解的方法中,本篇內容筆者講解一下使用@ControllerAdvice和@ExceptionHandler註解,自定義全局異常處理類,統一處理異常。
一、@ExceptionHandler註解介紹
啓動應用後,@ExceptionHandler註解都會作用在被@RequestMapping註解的方法上。
@ExceptionHandler 攔截了異常,我們可以通過該註解的value實現自定義異常攔截處理。其中,@ExceptionHandler 配置的 value 指定需要攔截的異常類型。
二、自定義業務異常類和全局異常處理類
1、編寫自定義業務異常類:
package com.demo.serverProvider.entity;
/**
* 創建時間:2019年3月2日 上午11:22:09
* 項目名稱:server-provider
* 類說明:自定義業務異常類
* @author guobinhui
* @since JDK 1.8.0_51
*/
public class BizException extends RuntimeException{
private static final long serialVersionUID = 2870428181462432015L;
private String code;
private String msg;
public BizException(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
注:spring 對於 RuntimeException 異常纔會進行事務回滾。
2、編寫全局異常處理類
package com.demo.serverProvider.handler;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.demo.serverProvider.entity.BizException;
/**
* 創建時間:2019年3月2日 上午11:27:02
* 項目名稱:server-provider
* 類說明:自定義全局異常處理類
* @author guobinhui
* @since JDK 1.8.0_51
*/
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 全局異常捕捉處理
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map<String,Object> defaultExceptionHandler(Exception ex) {
Map <String,Object> map = new HashMap <String,Object> ();
map.put("code", 500);
map.put("msg", ex.getMessage());
return map;
}
/**
* 攔截捕捉自定義業務異常 BizException.class
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = BizException.class)
public Map<String,Object> defaultExceptionHandler(BizException ex) {
Map<String,Object> map = new HashMap<String,Object>();
map.put("code", ex.getCode());
map.put("msg", ex.getMsg());
return map;
}
}
3、controller中拋出異常進行測試
package com.demo.serverProvider.controller;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.demo.serverProvider.entity.BizException;
/**
* 創建時間:2019年3月1日 下午4:03:44
* 項目名稱:server-provider
* 類說明:
* @author guobinhui
* @since JDK 1.8.0_51
*/
@RestController
@RequestMapping(value="/fileHandler")
public class ReadFilesController {
@RequestMapping("/test")
public String test() throws BizException{
StringBuffer message = new StringBuffer();
message.append("出現異常:【");
throw new BizException("400", message.toString() +"數據錯誤】");
}
}
啓動應用,訪問:http://localhost:8891/fileHandler/test,正常顯示以下json內容,證明業務異常已經被自定義異常處理類成功攔截
<Map>
<msg>出現異常:【數據錯誤】</msg>
<code>400</code>
</Map>
如果不需要返回json數據,而要渲染某個頁面模板返回給瀏覽器,那麼異常處理類GlobalExceptionHandler中可以這麼實現:
@ExceptionHandler(value = BizException.class)
public ModelAndView defaultExceptionHandler(BizException ex) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("code", ex.getCode());
modelAndView.addObject("msg", ex.getMsg());
return modelAndView;
}
在 templates 目錄下,添加 error.ftl(這裏使用freemarker) 進行渲染:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>異常頁面</title>
</head>
<body>
<h1>${code}</h1>
<h1>${msg}</h1>
</body>
</html>
重啓應用,http://localhost:8891/fileHandler/test 顯示自定義的異常頁面內容。
歡迎各位開發者朋友一起交流。筆者電話(微信):18629374628