在處理程序過程中,我們總是會需要處理一些異常,有時需要在報錯的同時給前端和客戶提示,此時一種通常的做法是在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;
}
}
這樣就可以優雅的提示報錯了: