我们要通过实现三个类,来实现一个web后端的全局异常管理功能,捕获controller层异常,封装成map集合,进行返回
1.实现异常处理的工具类
实现一个imooc.naga.core.exception,异常处理的包,定义两个类分别是:1.系统返回状态标识码实体类,2:封装了异常状态值,和异常信息内容的实体类
1.系统返回状态标识码实体类
package imooc.naga.core.exception;
/**
* 定义我们系统返回值的状态标志
*/
public class ErrorCodes {
//系统正常返回
public static final int SYSTEM_SUCCESS=200;
//系统异常
public static final int SYSTEM_EXCEPTION=100;
//系统输入参数异常
public static final int ERROR_PARAM=101;
//密码错误
public static final int ERROR_USER_NOT_EXISTS=102;
//权限不足
public static final int ERROR_PERMISSION=104;
}
2.封装了异常状态值,和异常信息内容的实体类
package imooc.naga.core.exception;
import lombok.Data;
@Data
public class NageExeception extends RuntimeException{
private String errorMessage;
private int errorCode;
public NageExeception(String errorMessage,int errorCode){
this.errorMessage = errorMessage;
this.errorCode = errorCode;
}
}
2.实现一个controller层的异常捕获类
package imooc.naga.server;
import imooc.naga.core.exception.ErrorCodes;
import imooc.naga.core.exception.NageExeception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 实现的就是对Controller层,全局的一个异常管理,将异常捕获,封装成map集合
*/
@ControllerAdvice //TODO:@ControllerAdvice与@ExceptionHandler配合使用捕获全局的异常,拦截controller所有抛出的异常
public class BaseController {
protected SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 实现方法,拦截controller所有抛出的异常
*/
@ExceptionHandler
@ResponseBody
//你的返回值将存在response的body中返回到前端,前端接收后会显示数据到页面,页面不会跳转.如果不加的话
// 返回值将会作为url的一部分,也就是页面会进行跳转,跳转到你返回的路径。
public Map<String ,Object>exceptionHandle(Exception ex, HttpServletResponse response){
//检查exception是否为我们自己定义的naga异常,如果是,就是我们系统识别的异常,给前端返回的异常
//如果不是就是系统运行出现了异常
//TODO:isAssignableFrom:确定此{@code Class}对象表示的类或接口是否与指定的{{code code}参数
// 表示的类或接口相同,或者是其超类或父接口。
if (NageExeception.class.isAssignableFrom(ex.getClass())){
NageExeception ng = (NageExeception)ex;
//返回
return getResultMap(ng.getErrorCode(),ng.getErrorMessage(),null);
}else{
//返回
return getError(ErrorCodes.SYSTEM_EXCEPTION,ex.getMessage());
}
}
//TODO:protected:访问权限为:class类内,package包内,extends子类
/**
* 传入的一定是错误状态码
* @param errcode:错误状态码
* @param errMsg:错误状态信息
* @return:Map<String,Object>
*/
protected Map<String,Object> getError(int errcode,String errMsg){
return getResultMap(errcode,null,null);
}
/**
* 将状态码以及状态信息内容,封装到一个hashmap集合进行饭局
* @param code:状态码
* @param data:状态信息
* @param extraMap:其他扩展内容
* @return:Map<String,Objrct>
*/
protected Map<String,Object> getResultMap(Integer code,Object data,Map<String,Object>extraMap){
String currentTime = sdf.format(new Date());
HashMap<String, Object> result = new HashMap<>();
result.put("currentTime",currentTime);
if (code ==null || code.equals(ErrorCodes.SYSTEM_SUCCESS)){
result.put("code",ErrorCodes.SYSTEM_SUCCESS);
result.put("data",data);
}else {
result.put("code",code);
result.put("msg",data);
}
//判断一下我们额外增加extraMap
if (extraMap!=null&&extraMap.isEmpty()){
result.putAll(extraMap);
}
return result;
}
}