使用@ExceptionHandler實現全局拋異常,完成優雅的報錯提示和程序處理

在處理程序過程中,我們總是會需要處理一些異常,有時需要在報錯的同時給前端和客戶提示,此時一種通常的做法是在service拋異常,然後在controller層try-catch住給以錯誤信息和錯誤碼的提示。這樣會顯得比較亂,controller層到處是try-catch。此時使用@ExceptionHandler能夠統一處理提示異常,處理方式更加優雅。
1.全局處理類:

@ControllerAdvice
public class GlobalExceptionHandle {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@ExceptionHandler
	@ResponseBody
	public Object handleException(HttpServletRequest req, Exception exception) throws Exception {

		String uri = req.getRequestURI();
		JsonView<Object> json = new JsonView<Object>();
		// 自定義的邏輯異常
		if (exception instanceof CustomException) {
			CustomException e = (CustomException) exception;
			int erroCode = e.getRtn().getCode();
			String msg=null;
			if(StringUtils.isNotBlank(e.getMsg())){
				msg=e.getMsg();
			}else{
				msg = e.getRtn().getMsg();
			}
			json.setCode(erroCode);
			json.setMsg(msg);
			json.setErrorData(e.getErrorData());
			logger.warn("uri:" + uri + "\n" + "CustomException log.", exception);
		} else {
			json.setCode(ExceptionCodeEnum.UNKNOW_ERROR.getCode());
			json.setMsg(ExceptionCodeEnum.UNKNOW_ERROR.getMsg());
			logger.error("uri:" + uri + "\n" + "unknow exception log.", exception);
		}
		return json;
	}
}

2.自定義異常:

package com.weiqu.compose.exception;

import com.weiqu.compose.util.common.ExceptionCodeEnum;

public class CustomException extends RuntimeException{

	private static final long serialVersionUID = 1L;
	private ExceptionCodeEnum rtn;
	private Object errorData;
    private String msg;

	public CustomException(ExceptionCodeEnum rtn) {
		super(rtn.getMsg());
		this.rtn = rtn;
	}
	
	public CustomException(ExceptionCodeEnum rtn, Object errorData) {
		super(rtn.getMsg());
		this.rtn = rtn;
		this.errorData = errorData;
	}

	public CustomException(ExceptionCodeEnum rtn,String msg) {
		super(msg);
		this.rtn = rtn;
		this.msg=msg;
	}

	public ExceptionCodeEnum getRtn() {
		return rtn;
	}

	public void setRtn(ExceptionCodeEnum rtn) {
		this.rtn = rtn;
	}

	public Object getErrorData() {
		return errorData;
	}

	public void setErrorData(Object errorData) {
		this.errorData = errorData;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}


}

3.自定義異常枚舉:

package com.weiqu.compose.util.common;

import static com.weiqu.compose.common.enums.ErrcodeNamespace.NS_GENERAL;

public enum ExceptionCodeEnum {
	
	/**
	 * 用戶操作以2開頭  4位數
	 * 視頻操作以1開頭 4位數
	 */
  UNKNOW_ERROR(NS_GENERAL,-111,"未知系統異常,請聯繫管理員"),
  DATA_ERROR(NS_GENERAL,-222,"數據異常,請聯繫管理員"),
  SYSTEM_ERROR(NS_GENERAL,-1,"操作失敗"),
  BASEPARAM_ERROR(NS_GENERAL,1,"基礎參數不全"),
  USER_IS_UNVALID(NS_GENERAL,2,"用戶操作校權不通過"),
  PARAM_ERROR(NS_GENERAL,3,"參數不對"),
    ;

	private ExceptionCodeEnum(String namespace, int code, String msg) {
		this.code = code;
		this.msg = msg;
		this.namespace = namespace;
	}

	private int code;
	private String msg;
	private String namespace;

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public String getNamespace() {
		return namespace;
	}

	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	@Override
	public String toString() {
		return String.format("[code=%s, msg=%s]", this.code, this.msg);
	}

}

4.controller層測試:

package com.weiqu.compose.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.weiqu.compose.exception.CustomException;
import com.weiqu.compose.util.common.ExceptionCodeEnum;
import com.weiqu.compose.util.common.JsonView;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@Api(description = "測試接口")
@RequestMapping(value = "/test")
public class TestController {
	@RequestMapping(value = "/testException", method = RequestMethod.GET)
    public Map<String,String> test(String msg) {
    	Map<String,String> test = new HashMap<>();
    	if("throws".equals(msg)){
    		throw new CustomException(ExceptionCodeEnum.UNKNOW_ERROR,"測試報錯");
    	}else{
    		test.put("fdsafasd", "fdasfas");
    	}
    	return test;
    }
}

這樣就可以優雅的提示報錯了:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章