在处理程序过程中,我们总是会需要处理一些异常,有时需要在报错的同时给前端和客户提示,此时一种通常的做法是在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;
}
}
这样就可以优雅的提示报错了: