当我们使用SpringBoot开发应用程序时,难免会遇到各种异常,在没有对异常进行处理时,用户会得到一些看不懂或不能理解的提示信息,这对于用户来说是非常不友好的,所以我们需要设置全局异常处理方式来帮助用户更好地理解我们的应用程序。
以下是关于SpringBoot全局异常处理的完整攻略,包括两个示例:
1. 全局异常处理方式
在SpringBoot中,我们可以通过实现@ControllerAdvice
注解的ExceptionHandler
方法来设置全局异常处理方式,如下所示:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(Exception ex, HttpServletRequest req) {
// 判断是否为AJAX请求
if (isAjaxRequest(req)) {
// 处理AJAX请求异常
return handleAjaxException(ex);
} else {
// 处理普通请求异常
return handleNormalException(ex);
}
}
// 判断是否为AJAX请求
private boolean isAjaxRequest(HttpServletRequest req) {
return "XMLHttpRequest".equals(req.getHeader("X-Requested-With"));
}
// 处理AJAX请求异常
private String handleAjaxException(Exception ex) {
// 处理异常信息
return "ajax_error";
}
// 处理普通请求异常
private String handleNormalException(Exception ex) {
// 处理异常信息
return "error";
}
}
在上面的代码中,我们首先定义了一个GlobalExceptionHandler
类,并使用@ControllerAdvice
注解来标记它是一个全局异常处理类。然后,我们使用@ExceptionHandler(Exception.class)
注解来标记当程序发生未知异常时,使用handleException
方法来处理异常。
在handleException
方法中,我们首先判断请求是否为AJAX请求,如果是,则调用handleAjaxException
方法来处理。如果不是,则调用handleNormalException
方法来处理。
在handleAjaxException
方法中,我们返回一个字符串ajax_error
,其实这里可以返回一个JSON对象,以便传递更多的异常信息给前端。
在handleNormalException
方法中,我们返回一个字符串error
,表示出现异常时跳转到一个错误页面。
2. 全局异常处理示例
下面是一个SpringBoot应用程序中的全局异常处理示例。
2.1 异常处理类
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex, HttpServletRequest req) {
ModelAndView mv = new ModelAndView();
mv.addObject("exception", ex);
mv.setViewName("error");
return mv;
}
}
在上面的代码中,我们定义了一个GlobalExceptionHandler
类,并使用@ControllerAdvice
注解来标记它是一个全局异常处理类。然后,我们使用@ExceptionHandler(Exception.class)
注解来标记当程序发生未知异常时,使用handleException
方法来处理异常。
在handleException
方法中,我们首先创建一个ModelAndView
对象,并将异常信息添加到该对象中。然后,我们将该对象的viewName设置为error
,表示出现异常时跳转到一个错误页面。
2.2 控制器类
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Integer id) {
if (id == 1) {
throw new RuntimeException("查询失败");
}
User user = new User();
user.setId(id);
user.setName("Tom");
user.setAge(20);
return user;
}
}
在上面的代码中,我们定义了一个UserController
类,并使用@RestController
注解来标记它是一个控制器类。然后,我们定义了一个getUser
方法,用于查询用户信息。
在getUser
方法中,如果查询的用户ID为1,则抛出一个运行时异常,表示查询失败。
2.3 错误页面
在SpringBoot中,我们可以在static目录下添加一个error.html文件来作为错误页面,如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>出错了</title>
</head>
<body>
<h1>出错了</h1>
<p>错误信息:${exception.message }</p>
</body>
</html>
在上面的代码中,我们首先定义了一个error.html
页面,并使用${exception.message}
来输出异常信息。
2.4 测试结果
在浏览器中访问http://localhost:8080/user/1
,我们会得到以下错误信息:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jul 05 15:52:17 CST 2021
There was an unexpected error (type=Internal Server Error, status=500).
查询失败
说明程序发生了运行时异常,并且没有显示出我们自定义的错误页面。
下面我们打开浏览器的开发者工具(按F12),选择Network
选项卡自己再输入地址测试,查看响应内容,我们会发现返回了以下JSON结构:
{
"timestamp": "2021-07-05T08:51:15.650+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "查询失败",
"path": "/user/1"
}
这就是我们设置全局异常处理方式后返回的JSON对象,其中message
字段中包含了异常信息。但是,我们期望的是跳转到我们自己定义的错误页面,所以我们需要调整GlobalExceptionHandler
类中的handleException
方法。
2.5 修改异常处理类
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex, HttpServletRequest req) {
ModelAndView mv = new ModelAndView();
mv.addObject("exception", ex);
// 判断是否为AJAX请求
if ("XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) {
// AJAX请求异常
mv.setViewName("ajax_error");
} else {
// 普通请求异常
mv.setViewName("error");
}
return mv;
}
}
在上面的代码中,我们现在将错误信息包装成ModelAndView返回,并根据请求的类型判断是返回错误页面还是返回JSON对象。如果是AJAX请求,则返回ajax_error.html
页面,否则返回error.html
页面。
2.6 创建AJAX异常处理页面
我们将在static目录下创建一个ajax_error.html
文件,用于输出异常信息,在该文件中定义了以下内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX出错了</title>
</head>
<body>
<h1>AJAX出错了</h1>
<p>错误信息:${exception.message }</p>
</body>
</html>
在上面的代码中,我们首先定义了一个ajax_error.html
页面,并使用${exception.message}
来输出异常信息。
2.7 测试结果
在浏览器中访问http://localhost:8080/user/1
,我们现在会得到以下错误信息:
AJAX出错了
错误信息:查询失败
这就是我们自定义的错误页面显示的错误信息。
如果我们使用Postman等工具进行测试,我们可以得到以下JSON响应:
{
"exception": "java.lang.RuntimeException",
"message": "查询失败",
"path": "/user/1"
}
这就是我们设置全局异常处理方式后返回的JSON对象,其中message
字段中包含了异常信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot全局异常处理方式 - Python技术站