天天看點

SpringBoot @ControllerAdvice注解自定義全局異常處理類 統一處理異常

在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 >
<head>
    <meta charset="UTF-8">
    <title>異常頁面</title>
</head>
<body>
    <h1>${code}</h1>
    <h1>${msg}</h1>
</body>
</html>
           

重新開機應用,http://localhost:8891/fileHandler/test 顯示自定義的異常頁面内容。

歡迎各位開發者朋友一起交流。筆者電話(微信):18629374628