异常处理
异常(exception) 是程序运行过程中发生的事件, 该事件可以中断程序指令的正常执行流程.
1当Java程序运行时出现问题时,系统会自动检测到该错误,并立即生成一个与该错误对应的异常对象
2:然后把该异常对象提交给JAVA虚拟机
3:JAVA虚拟机会自动寻找相应的处理代码来处理这个异常,如果没有找到,则程序终止
4:程序员可以自己编写代码来扑捉可能出现的异常,并编写代码来处理相应的异常.
@ControllerAdvice注解
- 定义统一的异常处理类,是Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强。
- @ControllerAdvice是一个@Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。
- Spring4之前,@ControllerAdvice在同一调度的Servlet中协助所有控制器。Spring4已经改变:@ControllerAdvice支持配置控制器的子集,而默认的行为仍然可以利用。
- 在Spring4中, @ControllerAdvice通过annotations(), basePackageClasses(), basePackages()方法定制用于选择控制器子集。
自定义异常类
如果想要定义属于自己的异常类可以继承两种父类:Exception(必须处理)、RuntimeException(选择性处理)
-
Java中所有异常的父类是Throwable类,在Throwable类下有两大子类:
-
一个是Error类,指系统错误异常,例如:VirtualMachineError 虚拟机错误,ThreadDeath 线程死锁。一般如果是Error类的异常的话,就是程序的硬伤,就好比是工厂里断水断电,机器损坏了。
-
另一个是Exception类,指编码、环境、用户操作输入等异常,这个是比较常见的异常类,
- Exception类下面又有两个子类,RuntimeException 非检查异常和检查异常,
- 非检查又称为运行时异常,在RuntimeException异常中有几个常见的子类
-
InputMismatchException | 输入不匹配异常 |
ArithmeticException | 算术运算异常 |
NullPointerException | 空指针异常 |
ArrayIndexOutOfBoundsException | 数组下标越界异常 |
ClassCastException | 类型转换异常 |
- 检查异常中的子类有:
\\ | \\ |
---|---|
IOException | 文件异常 |
SQLException | SQL数据库错误异常 |
package com.zz.exception;
public class UserNotExistException extends RuntimeException {
private static final long serialVersionUID = -1574716826948451793L;
private String id;
public UserNotExistException(String id){
super("user not exist");
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
创建统一异常处理类
通过 @ControllerAdvice 和 @ExceptionHandler实现处理controller层的异常
- @ResponseBody //表示返回的对象,Spring会自动把该对象进行json转化,最后写入到Response中
- @ExceptionHandler(UserNotExistException.class)
- 表示让Spring捕获到所有抛出的UserNotExistException异常,并交由这个被注解的方法处理。
- 表示catch 到这个异常类型,并且在方法中处理, 不同的异常,可以通过不同的方法处理,每个方法上面都是通过这个注解括号里面的异常类来设置需要处理的异常类型。
- @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
- 表示设置状态码。
- ResponseStatus注解是修饰类的
它有两个属性,value属性是http状态码,比如404,500等。reason是错误信息
‘500’ : ‘Internal Server Error’, //内部服务器错误
package com.zz.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class ControllerExceptionHandler {
//返回json的错误信息
@ExceptionHandler(UserNotExistException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, Object> handleUserNotExistsException(UserNotExistException e) {
Map<String, Object> map = new HashMap<>();
map.put("id", e.getId());
map.put("message", e.getMessage());
return map;
}
//错误以后,跳转到自己定义的错误页面
@ExceptionHandler(ArithmeticException.class)
public String handle1(ArithmeticException e) {
System.out.println("handle1 500*到了**************");
return "/500.html";
}
}
controller
package com.zz.controller;
import com.zz.exception.UserNotExistException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("/{id:\\d+}")
public void get(@PathVariable String id) {
throw new UserNotExistException(id);
}
@GetMapping("error2")
public void get2() {
int a=1/0;
}
}
参考:
SpringMVC重要注解(二)@ControllerAdvice:https://blog.csdn.net/w372426096/article/details/78429141
SpringBoot 统一异常处理 ControllerAdvice:https://blog.csdn.net/zhaoyanjun6/article/details/80678034
Java RuntimeException 处理汇总:https://www.cnblogs.com/jpwz/p/5669522.html
SpringBoot 统一异常处理:https://www.jianshu.com/p/7c4d3c7a28ae
HttpStatus详解:https://blog.csdn.net/csdn1844295154/article/details/78980174
常见的几种RuntimeException及其详解:https://blog.csdn.net/qq_32595075/article/details/80059834