异常处理之前,先搭建一个基本的Spring Boot项目开启Spring Boot。然后引入mybatis-spring-boot-starter
目录
Spring Boot对异常的处理有一套默认的机制:当应用中产生异常时,Spring Boot根据发送请求头中的
accept
是否包含text/html
来分别返回不同的响应信息。当从浏览器地址栏中访问应用接口时,请求头中的accept
便会包含text/html
信息,产生异常时,Spring Boot通过org.springframework.web.servlet.ModelAndView
对象来装载异常信息,并以HTML的格式返回;而当从客户端访问应用接口产生异常时(客户端访问时,请求头中的accept
不包含text/html
),Spring Boot则以JSON的格式返回异常信息。下面来验证一下。
默认异常处理机制
定义一个controller
@Controller
public class TestController {
@GetMapping("/test/{id:\\d+}")
public String index(@PathVariable String id) {
throw new RuntimeException("Ex-girlfriend anomaly");
}
}
使用浏览器访问http://localhost:8080/test/12
看到页面返回了一些异常描述,并且请求头的accpet
包含了text/html
片段。
使用模拟发送REST请求的Chrome插件Restlet Client发送http://localhost:8080/test/12
可以看到请求头的accept
值为*/*
,并且返回一段JSON格式的信息。
查看Spring Boot的BasicErrorController
类便可看到这一默认机制的具体实现:
可看到
errorHtml
和error
方法的请求地址和方法是一样的,唯一的区别就是errorHtml
通过produces = {"text/html"}
判断请求头的accpet
属性中是否包含text/html
。
自定义html异常页面
可以通过在src/main/resources/resources/error
路径下定义异常页面,比如定义一个500.html页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>500</title>
</head>
<body>
女友查房异常
</body>
</html>
自定义异常处理
除了可以通过自定义html异常页面来改变浏览器访问接口时产生的异常信息,我们也可以自定义异常处理来改表默认的客户端访问接口产生的异常信息。
我们手动定义一个GirlFriendException(前女友异常)继承RuntimeException
public class GirlFriendException extends RuntimeException {
private String id;
public GirlFriendException(String message, String id) {
super(message);
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
然后定义一个Controller异常处理类ControllerExceptionHandler
@ControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(GirlFriendException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ModelAndView handleUserNotExistsException(GirlFriendException e) {
ModelAndView modelAndView=new ModelAndView();
Map<String, Object> map = new HashMap<>();
map.put("id", e.getId());
map.put("message", e.getMessage());
modelAndView.addObject("map",map);
modelAndView.setViewName("500");
return modelAndView;
}
}
在templates下添加500页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>500</h1>
</body>
</html>
在TestController抛出自定义异常
@Controller
public class TestController {
@GetMapping("/test/{id:\\d+}")
public String index(@PathVariable String id) {
throw new GirlFriendException("Ex-girlfriend anomaly",id);
}
}