文章目录
- 异常处理
- 介绍
- 自定义异常页面
- 文档:
- 自定义异常页面说明
- 自定义异常页面-应用实例
- 需求:
- 代码实现
- 全局异常
- 说明
- 全局异常-应用实例
- 需求:
- 代码实现
- 完成测试
- 自定义异常
- 说明
- 自定义异常-应用实例
- 需求:
- 代码实现
- 完成测试
- 注意事项
- 完成测试
异常处理
介绍
- 默认情况下,Spring Boot 提供/error 处理所有错误的映射
- 对于机器客户端,它将生成JSON 响应,其中包含错误,HTTP 状态和异常消息的详细信息。对于浏览器客户端,响应一个"whitelabel"错误视图,以HTML 格式呈现相同的数据
自定义异常页面
文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.developing-web-applications.spring-mvc.error-handling.error-pages
自定义异常页面说明
1、如何找到这个文档位置, 看下面一步步的指引
https://docs.spring.io/spring-boot/docs/current/reference/html/index.html => a single HTML page=> 8.web => servlet web application => The “Spring Web MVC Framework” => ErrorHandling => Custom Error Pages
自定义异常页面-应用实例
需求:
自定义404.html 500.html 4xx.html 5xx.html 当发生相应错误时,显示自定义的页面信息
代码实现
- 创建4 个页面, 这几个页面拷贝即可(这里使用Thymeleaf需要引入命名空间)
创建4xx.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
<h1>4xx 发生错误了:)</h1>
错误状态码: <h1 th:text="${status}"></h1><br/>
错误信息: <h1 th:text="${error}"></h1><br/>
<a href='#' th:href="@{/}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>
创建404.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
<h1>4o4 Not Found</h1>
<a href='#' th:href="@{/}">返回主页面</a><br/>
状态码: <h1 th:text="${status}"></h1><br/>
错误信息: <h1 th:text="${error}"></h1>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>
创建5xx.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
<h1>5xx 发生错误了:)</h1><br/>
错误状态码: <h1 th:text="${status}"></h1><br/>
错误信息: <h1 th:text="${error}"></h1><br/>
<a href='#' th:href="@{/}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>
创建500.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
<h1>500 内部服务器出现了问题</h1><br/>
状态码: <h1 th:text="${status}"></h1><br/>
错误信息: <h1 th:text="${error}"></h1><br/>
<a href='#' th:href="@{/}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>
- 创建com/nlc/usersys/controller/MyErrorController.java , 用于模拟错误
@Controller
public class MyErrorController {
//模拟一个服务器内部错误500
@GetMapping("/err")
public String err() {
int i = 10 / 0; //算术异常
return "manage";
}
//这里我们配置的是Post方式请求 /err2
//一会使用 get方式来请求 /err2 , 这样就会出现一个405开头的客户端错误
@PostMapping("/err2")
public String err2() {
//..
return "manage";
}
}
- 完成测试
● 需要先登录,再进行测试,否则会被拦截器打回登录页面
● 对于/err2 , 使用get 方式去请求,就会生成400 错误, 可以看到4xx.html
浏览器输入:http://localhost:8080/xx
浏览器输入:http://localhost:8080/err2
浏览器输入:http://localhost:8080/err
全局异常
说明
- @ControllerAdvice+@ExceptionHandler 处理全局异常
- 底层是ExceptionHandlerExceptionResolver 支持的
全局异常-应用实例
需求:
- 演示全局异常使用, 当发生ArithmeticException、NullPointerException 时,不使用默认异常机制匹配的xxx.html , 而是显示全局异常机制指定的错误页面
代码实现
- 创建com/nlc/usersys/exception/GlobalExceptionHandler.java
/**
* @ControllerAdvice: 使用它可以标识一个全局异常处理器/对象
* 会注入到spring容器
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
//1、编写方法,处理指定异常, 比如我们处理算术异常和空指针异常, 可以指定多个异常
//2. 这里要处理的异常,由程序员来指定
//3. Exception e : 表示异常发生后,传递的异常对象
//4. Model model: 可以将我们的异常信息,放入model,并传递给显示页面
@ExceptionHandler({ArithmeticException.class, NullPointerException.class})
public String handleAritException(Exception e, Model model, HandlerMethod handlerMethod) {
log.info("异常信息={}", e.getMessage());
//这里将发生的异常信息放入到model,可以再错误页面取出显示
model.addAttribute("msg", e.getMessage());
//得到异常发生的方法是哪个
log.info("异常发生的方法是={}", handlerMethod.getMethod());
return "/error/global"; //视图地址
}
}
- 创建templates/error/global.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>全局异常-显示页面</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
<h1>全局异常/错误 发生了:)</h1><br/>
异常/错误信息: <h1 th:text="${msg}"></h1><br/>
<a href='#' th:href="@{/}">返回主页面</a>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>
完成测试
浏览器输入:http://localhost:8080/err
自定义异常
说明
- 如果Spring Boot 提供的异常不能满足开发需求,程序员也可以自定义异常.
- @ResponseStatus+自定义异常
- 底层是ResponseStatusExceptionResolver ,底层调用response.sendError(statusCode,resolvedReason);
- 当抛出自定义异常后,仍然会根据状态码,去匹配使用x.html 显示
自定义异常-应用实例
需求:
自定义一个异常AccessException, 当用户访问某个无权访问的路径时,抛出该异常,显示自定义异常状态码
代码实现
- 创建com/nlc/usersys/exception/AccessException.java
/**
* AccessException : 我们自定义的一个异常
* value = HttpStatus.FORBIDDEN: 表示发生AccessException异常,我们通过http协议返回的状态码 403
* 这个状态码和自定义异常的对应关系是由程序员来决定[尽量合理来设置]
* 光标在HttpStatus.FORBIDDEN上CTRL+B可以查看源码看它的状态码
*/
//自定义异常,也会根据状态码,匹配到对应的错误页面显示
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class AccessException extends RuntimeException {
//提供一个构造器,可以指定信息
public AccessException(String message) {
super(message);
}
//显示的定义一下无参构造器
public AccessException() {
}
}
- 修改MyErrorController.java
@Controller
public class MyErrorController {
//模拟一个服务器内部错误500
@GetMapping("/err")
public String err() {
int i = 10 / 0; //算术异常
return "manage";
}
//这里我们配置的是Post方式请求 /err2
//一会使用 get方式来请求 /err2 , 这样就会出现一个405开头的客户端错误
@PostMapping("/err2")
public String err2() {
//..
return "manage";
}
//编写方法,模拟一个AccessException
@GetMapping("/err3")
public String err3(String name) {
//如果用户不是tom,我们就认为,无权访问-模拟
if(!"tom".equals(name)) {
//throw new AccessException();
throw new AccessException("自定义的AccessException..");
}
return "manage";//视图地址, 请求转发
}
}
完成测试
浏览器http://localhost:8080/err3
注意事项
1.如果我们将自定义异常放入全局异常处理器,会走全局异常处理机制。
2.放入全局异常就是按照Java的异常类型机制处理,不会按照状态码进行处理。
3.可以自己看看显示效果并Debug,也可以自己设置异常信息。
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
//1、编写方法,处理指定异常, 比如我们处理算术异常和空指针异常, 可以指定多个异常
//2. 这里要处理的异常,由程序员来指定
//3. Exception e : 表示异常发生后,传递的异常对象
//4. Model model: 可以将我们的异常信息,放入model,并传递给显示页面
@ExceptionHandler({ArithmeticException.class, NullPointerException.class,AccessException.class})
public String handleAritException(Exception e, Model model, HandlerMethod handlerMethod) {
log.info("异常信息={}", e.getMessage());
//这里将发生的异常信息放入到model,可以再错误页面取出显示
model.addAttribute("msg", e.getMessage());
//得到异常发生的方法是哪个
log.info("异常发生的方法是={}", handlerMethod.getMethod());
return "/error/global"; //视图地址
}
}
完成测试
浏览器http://localhost:8080/err3
(Exception e, Model model, HandlerMethod handlerMethod) {
log.info("异常信息={}", e.getMessage());
//这里将发生的异常信息放入到model,可以再错误页面取出显示
model.addAttribute("msg", e.getMessage());
//得到异常发生的方法是哪个
log.info("异常发生的方法是={}", handlerMethod.getMethod());
return "/error/global"; //视图地址
}
}
#### 完成测试
浏览器http://localhost:8080/err3
![image-20230816115335703](https://img-blog.csdnimg.cn/img_convert/3aa3a4c9680d246ae99362a27eb69830.png)