1.了解异常
1.Throwable是从Object直接继承而来(这是Java系统所强制要求的),是Error和Exception的父类,是所有异常对象的根基类,用来定义所有可以作为异常被抛出来的类。
2.Error和Exception区分:
Error(错误)是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防
Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行
Error是一种严重的问题,应用程序不应该捕捉它。 Exception一般可能是程序和业务上的错误,是可以恢复的。
```java
Exception
│
├─ RuntimeException
│ │
│ ├─ NullPointerException
│ │
│ ├─ IndexOutOfBoundsException
│ │
│ ├─ SecurityException
│ │
│ └─ IllegalArgumentException
│ │
│ └─ NumberFormatException
│
├─ IOException
│ │
│ ├─ UnsupportedCharsetException
│ │
│ ├─ FileNotFoundException
│ │
│ └─ SocketException
│
├─ ParseException
│
├─ GeneralSecurityException
│
├─ SQLException
│
└─ TimeoutException
```
3.Exception又分为RunTimeException和其他Exception。
RunTimeException和其他Exception区分:
其他Exception,受检查异常。可以理解为错误,必须要开发者解决以后才能编译通过,解决的方法有两种,1:用throws字句声明抛出,交给它的父类处理 2,try-catch捕获处理。
RunTimeException:运行时异常,又称不受检查异常,因为不受检查,所以在代码中可能有RunTimeException的时候,Java编译检查时不会告诉你有这个异常,但是在实际运行代码时则会暴露出来,比如典型的1/0,空指针等。
一些主要子类对应的异常处理功能简要说明如下:
ArithmeticException——由于除数为0引起的异常;
ArrayStoreException——由于数组存储空间不够引起的异常;
ClassCastException—一当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常;
IllegalMonitorStateException——监控器状态出错引起的异常;
NegativeArraySizeException—一数组长度是负数,则产生异常;
NullPointerException—一程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常;
OutofMemoryException——用new语句创建对象时,如系统无法为其分配内存空 间则产生异常;
SecurityException——由于访问了不应访问的指针,使安全性出问题而引起异常;
IndexOutOfBoundsExcention——由于数组下标越界或字符串访问越界引起异常;
IOException——由于文件未找到、未打开或者I/O操作不能进行而引起异常;
ClassNotFoundException——未找到指定名字的类或接口引起异常;
CloneNotSupportedException——一程序中的一个对象引用Object类的clone方法,但 此对象并没有连接Cloneable接口,从而引起异常;
InterruptedException—一当一个线程处于等待状态时,另一个线程中断此线程,从 而引起异常,有关线程的内容,将在下一章讲述;
NoSuchMethodException一所调用的方法未找到,引起异常;
Illega1AccessExcePtion—一试图访问一个非public方法;
StringIndexOutOfBoundsException——访问字符串序号越界,引起异常;
ArrayIdexOutOfBoundsException—一访问数组元素下标越界,引起异常;
NumberFormatException——字符的UTF代码数据格式有错引起异常;
IllegalThreadException—一线程调用某个方法而所处状态不适当,引起异常;
FileNotFoundException——未找到指定文件引起异常;
EOFException——未完成输入操作即遇文件结束引起异常。
2.自定义异常
在一个稍微大点的项目中,可以自定义新的异常类型,但是,保持一个合理的异常继承体系还是有必要的。
一个常见的做法是自定义一个BaseException作为“根异常”,然后,派生出各种业务类型的异常。
BaseException需要从一个适合的Exception派生,通常建议从RuntimeException派生,spring 对于 RuntimeException 异常才会进行事务回滚。
public class BaseException extends RuntimeException {
}
其他业务类型的异常就可以从BaseException派生:
public class ParamNotFoundException extends BaseException {
}
public class UpdateFailedException extends BaseException {
}
...
自定义的BaseException应该提供多个构造方法,,让派生的异常能够有多的选择
public class BaseException extends RuntimeException {
public BaseException() {
super();
}
public BaseException(String message, Throwable cause) {
super(message, cause);
}
public BaseException(String message) {
super(message);
}
public BaseException(Throwable cause) {
super(cause);
}
}
另一种方法是用ControllerAdvice,定义一个全局异常处理类,去做全局异常捕捉处理,
如果全部异常处理返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。
1.自定义异常
public class MyException extends RuntimeException {
private int code;
private String msg;
public MyException(int code, String msg) {super(msg);this.code = code;this.msg = msg;}
public MyException(String msg){super(msg);this.msg = msg;}
public MyException(String msg,Throwable e){super(msg, e);this.msg = msg;}
public MyException(String msg,int code,Throwable e){super(msg, e);this.msg = msg;this.code = code; }
public String getMsg(){return msg;}
public void setMsg(String msg){this.msg = msg;}
public int getCode(){return code}
public void setCode(int code){this.code = code;}
}
2.编写全局异常处理类
@ControllerAdvice
public class MyControllerAdvice {
privateLogger logger =LoggerFactory.getLogger(getClass());
/**
* 全局异常捕捉处理
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(Exception.class)
public Map exceptionHandler(Exception ex) {
logger.error(ex.getMessage(),ex);
Map map = new HashMap();
map.put("code", 100);
map.put("msg", ex.getMessage());
return map;
}
/**
* 拦截捕捉自定义异常 MyException.class
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(MyException.class)
public Map myExceptionHandler(MyException ex) {
logger.error(ex.getMsg(),ex);
Map map = new HashMap();
map.put("code", ex.getCode());
map.put("msg", ex.getMsg());
return map;
}
@ExceptionHandler(DuplicateKeyException.class)
public Map duplicateKeyExceptionHandle(DuplicateKeyException ex){
logger.error(ex.getMessage(), ex);
Map map = new HashMap();
map.put("code", 105);
map.put("msg", "数据库中已存在该记录");
return map;
}