文章来源:https://blog.csdn.net/qq_29281307/article/details/109598176
先推荐两篇博客
https://blog.csdn.net/hao_kkkkk/article/details/80538955
https://blog.csdn.net/chang_li/article/details/71632547
上面两位博主已经将java处理异常的流程讲的很清楚了。
下面贴出我的代码:
用的是@ControllerAdvice
这个注解类有三个作用
1、全局异常处理
2、全局数据绑定
3、全局数据预处理
再贴一篇@ControllerAdvice的文章https://www.cnblogs.com/lenve/p/10748453.html
异常处理类如下:
package com.lenovoedu.config;
import com.lenovoedu.exception.RassCmsException;
import com.lenovoedu.exception.code.ErrorCode;
import com.lenovoedu.exception.code.MySQLAbnormalState;
import com.lenovoedu.utils.R;
import com.lenovoedu.utils.base.log.Logger;
import com.lenovoedu.utils.base.log.LoggerFactory;
import org.apache.commons.beanutils.ConversionException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.sql.SQLException;
import java.util.List;
/**
* 系统在启动时自动加载此类,整个系统发生异常,这个类统一处理。
*
* 参考MyControllerAdvice类的说明。
*/
@ControllerAdvice
public class GlobalExceptionHandle {
private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandle.class);
/**
* 操作数据库发生异常捕捉处理
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler(SQLException.class)
public R exceptionHandle(SQLException e) {
String errInfo = MySQLAbnormalState.errorInfo(e.getErrorCode());
logger.error("【操作数据库发生异常:" + errInfo + "】{}", e);
return R.error(e.getErrorCode(),"操作数据库发生异常:" + errInfo);
}
/**
* 系统发生转型异常捕捉处理
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler(ClassCastException.class)
public R exceptionHandle(ClassCastException e) {
logger.error("【系统发生转型异常】{}", e);
return R.error(ErrorCode.CLASS_CAST_ERROR.getCode(),ErrorCode.CLASS_CAST_ERROR.getMsg());
}
/**
* 方法参数异常捕捉处理
* @param de
* @return 出错信息的json
*/
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
public R exceptionHandle(MethodArgumentNotValidException de) {
List<FieldError> list = de.getBindingResult().getFieldErrors();
int size = list.size();
String[] errInfos = new String[size];
for(int i = 0; i < size; i ++) {
errInfos[i] = list.get(i).getDefaultMessage();
}
logger.error("【方法参数异常】{" + errInfos + "}", de);
return R.error(ErrorCode.METHOD_ARGUMENT_NOTVALID_ERROR.getCode(),ErrorCode.METHOD_ARGUMENT_NOTVALID_ERROR.getMsg());
}
/**
* 使用BeanUtils时发生异常!
* @param de
* @return 出错信息的json
*/
@ResponseBody
@ExceptionHandler(ConversionException.class)
public R exceptionHandle(ConversionException de) {
logger.error("【复制JavaBean的时候Date对象没有值!】{}", de);
return R.error(ErrorCode.NO_VALUE_SPECIFIED_FOR_DATE.getCode(),ErrorCode.NO_VALUE_SPECIFIED_FOR_DATE.getMsg());
}
/**
* 全局自定义异常捕捉处理
* @param de
* @return 出错信息的json
*/
@ResponseBody
@ExceptionHandler(RassCmsException.class)
public R exceptionHandle(RassCmsException de) {
logger.error("【自定义异常】{}", de);
return R.error(de.getCode(),de.getMessage());
}
}
统一结果封装对象如下:
package com.lenovoedu.utils;
import org.springframework.http.HttpStatus;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 项目名称:rasscms
* 类名称:R
* 类描述:消息封装
* 创建人:ygl
* 创建时间:2020年10月22日11:03:42
* version 1.0
*/
public class R extends HashMap<String, Object> implements Serializable{
private static final long serialVersionUID = 4071500889040341654L;
public R() {
put("code", 0);
put("msg", "success");
}
public static R error() {
return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
}
public static R error(String msg) {
return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg);
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R ok() {
return new R();
}
@Override
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
自定义异常如下:
package com.lenovoedu.exception;
import com.lenovoedu.exception.code.ErrorCode;
public class RassCmsException extends RuntimeException {
private Integer code;
private Exception e;
/**
* 继承exception,加入错误状态值
* @param exceptionEnum
*/
public RassCmsException(ErrorCode exceptionEnum) {
super(exceptionEnum.getMsg());
this.code = exceptionEnum.getCode();
}
public RassCmsException(ErrorCode exceptionEnum,Exception e) {
super(exceptionEnum.getMsg(),e);
this.code = exceptionEnum.getCode();
}
/**
* 自定义错误信息
* @param message
* @param code
*/
public RassCmsException(String message, Integer code) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
自定义ErrorCode如下:
package com.lenovoedu.exception.code;
public enum ErrorCode {
SUCCESS(0,"成功"),
PARAMETER_ERROR(400,"参数错误"),
NEED_LOGIN_ERROR(401,"未登录,无权操作"),
URI_NOT_EXIST_ERROR(404,"资源不存在"),
SERVER_ERROR(500,"系统内部错误"),
CLASS_CAST_ERROR(10009, "系统发生转型异常!"),
METHOD_ARGUMENT_NOTVALID_ERROR(10010, "访问方法参数不正确!"),
NO_VALUE_SPECIFIED_FOR_DATE(10012, "复制JavaBean的时候Date对象没有值!"),
LOGIN_VERIFICATION_CODE_IS_WRONG(3001,"验证码错误"),
LOGIN_LOGIN_NAME_OR_PASSWORD_IS_WRONG(3002,"用户名或密码错误"),
LOGIN_LOGIN_TIME_IS_TOO_MUCH(3003,"登录失败次数过多,请稍后再试"),
LOGIN_ACCOUNT_IS_LOCKED(3004,"账号已被锁定"),
LOGIN_ACCOUNT_IS_DISABLED(3005,"账号已被禁用"),
LOGIN_ACCOUNT_IS_EXPIRED(3006,"账号已过期"),
FILE_TOO_LARGE(4001,"文件太大"),
FILETYPE_ERROR(4002,"文件类型错误"),
NO_HAVE_FILE(4003,"文件不存在");
private ErrorCode(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
private Integer code;
private String msg;
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
mysql异常信息集合如下:
package com.lenovoedu.exception.code;
import java.util.HashMap;
import java.util.Map;
public class MySQLAbnormalState {
private static Map<Integer, String> map;
static {
map = new HashMap<Integer, String>();
map.put(1005, "创建表失败!");
map.put(1006, "创建数据库失败!");
map.put(1007, "数据库已存在,创建数据库失败!");
map.put(1008, "数据库不存在,删除数据库失败!");
map.put(1009, "不能删除数据库文件导致删除数据库失败!");
map.put(1010, "不能删除数据目录导致删除数据库失败!");
map.put(1011, "删除数据库文件失败!");
map.put(1012, "不能读取系统表中的记录!");
map.put(1016, "文件无法打开,使用后台修复或者使用phpmyadmin进行修复。!");
map.put(1020, "记录已被其他用户修改!");
map.put(1021, "硬盘剩余空间不足,请加大硬盘可用空间!");
map.put(1022, "关键字重复,更改记录失败!");
map.put(1023, "关闭时发生错误!");
map.put(1024, "读文件错误!");
map.put(1025, "更改名字时发生错误!");
map.put(1026, "写文件错误!");
map.put(1032, "记录不存在!");
map.put(1036, "数据表是只读的,不能对它进行修改!");
map.put(1037, "系统内存不足,请重启数据库或重启服务器!");
map.put(1038, "用于排序的内存不足,请增大排序缓冲区!");
map.put(1040, "已到达数据库的最大连接数,请加大数据库可用连接数!");
map.put(1041, "系统内存不足!");
map.put(1042, "无效的主机名!");
map.put(1043, "无效连接!");
map.put(1044, "当前用户没有访问数据库的权限!");
map.put(1045, "不能连接数据库,用户名或密码错误!");
map.put(1048, "字段不能为空!");
map.put(1049, "数据库不存在!");
map.put(1050, "数据表已存在!");
map.put(1051, "数据表不存在!");
map.put(1054, "字段不存在!");
map.put(1064, "数据库SQL语法出现错误!");
map.put(1065, "无效的SQL语句,SQL语句为空!");
map.put(1081, "不能建立Socket连接!");
map.put(1114, "数据表已满,不能容纳任何记录!");
map.put(1116, "打开的数据表太多!");
map.put(1129, "数据库出现异常,请重启数据库!");
map.put(1130, "连接数据库失败,没有连接数据库的权限!");
map.put(1133, "数据库用户不存在!");
map.put(1141, "当前用户无权访问数据库!");
map.put(1142, "当前用户无权访问数据表!");
map.put(1143, "当前用户无权访问数据表中的字段!");
map.put(1146, "数据表不存在!");
map.put(1147, "未定义用户对数据表的访问权限!");
map.put(1149, "SQL语句语法错误!");
map.put(1158, "网络错误,出现读错误,请检查网络连接状况!");
map.put(1159, "网络错误,读超时,请检查网络连接状况!");
map.put(1160, "网络错误,出现写错误,请检查网络连接状况!");
map.put(1161, "网络错误,写超时,请检查网络连接状况!");
map.put(1062, "字段值重复,入库失败!");
map.put(1169, "字段值重复,更新记录失败!");
map.put(1177, "打开数据表失败!");
map.put(1180, "提交事务失败!");
map.put(1181, "回滚事务失败!");
map.put(1203, "当前用户和数据库建立的连接已到达数据库的最大连接数,请增大可用的数据库连接数或重启数据库!");
map.put(1205, "加锁超时!");
map.put(1211, "当前用户没有创建用户的权限!");
map.put(1216, "外键约束检查失败,更新子表记录失败!");
map.put(1217, "外键约束检查失败,删除或修改主表记录失败!");
map.put(1226, "当前用户使用的资源已超过所允许的资源,请重启数据库或重启服务器!");
map.put(1227, "权限不足,您无权进行此操作!");
map.put(1235, "MySQL版本过低,不具有本功能!");
map.put(1406, "您输入的值过长!");
}
public static String errorInfo(Integer code) {
return map.get(code);
}
}