下面是关于“SpringBoot详解实现自定义异常处理页面方法”的完整攻略:
SpringBoot详解实现自定义异常处理页面方法
前言
在我们的应用程序中,经常会遇到一些异常问题,比如资源不存在、参数错误等等,这时候我们就需要对这些异常进行统一处理,并且返回给用户友好的错误提示信息。在SpringBoot中,通过实现自定义异常处理页面方法,我们可以非常方便地实现这个需求。
实现步骤
创建自定义异常类
首先,我们需要创建一个自定义异常类,继承自Exception或RuntimeException,并且添加我们需要的构造函数,比如:
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
public ResourceNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
在这个例子中,我们创建了一个名为ResourceNotFoundException的自定义异常类,继承自RuntimeException类。我们添加了两个构造函数,一个只有异常信息,一个包含异常信息和Throwable(包含更详细的异常信息)参数。
创建统一异常处理类
接下来,我们需要创建一个统一异常处理类,用于捕获和处理应用程序中的异常,并且返回统一的错误响应给用户。示例代码如下:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException e) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), e.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
String errorMessage = fieldErrors.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), e.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
在这个例子中,我们使用@ControllerAdvice注解,创建了一个名为GlobalExceptionHandler的类,用于捕获所有的异常,并统一处理。在这个类中,我们添加了三个异常处理方法:
- handleResourceNotFoundException:用于处理资源不存在的异常,返回HTTP状态码404。
- handleMethodArgumentNotValidException:用于处理方法参数不合法的异常,返回HTTP状态码400。
- handleException:用于处理其他类型的异常,返回HTTP状态码500。
在每个异常处理方法中,我们创建了一个ErrorDetails对象,包含了异常发生的时间、异常信息和请求的描述信息。然后,我们使用ResponseEntity对象,将这个ErrorDetails对象返回给用户。
创建自定义错误页面
最后一步,我们需要创建自定义错误页面,用于展示错误信息给用户。在SpringBoot中,我们可以很方便地实现这个需求。示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Error Page</title>
</head>
<body>
<h1>Error Page</h1>
<div>
<h2>Timestamp</h2>
<pre th:text="${errorDetails.timestamp}"></pre>
</div>
<div>
<h2>Message</h2>
<pre th:text="${errorDetails.message}"></pre>
</div>
<div>
<h2>Description</h2>
<pre th:text="${errorDetails.description}"></pre>
</div>
</body>
</html>
在这个例子中,我们创建了一个名为error.html的自定义错误页面。在这个页面中,我们展示了异常发生的时间、异常信息和请求的描述信息,通过th:text指令动态渲染对应的数据。
示例
下面,我们演示一下如何使用上述步骤实现自定义异常处理页面的功能。
示例1
假设我们的应用程序中,存在一个名为UserController的Controller类,代码如下:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id).orElseThrow(() -> new ResourceNotFoundException("User not found with id " + id));
}
@PostMapping("")
public User createUser(@Valid @RequestBody User user) {
return userService.createUser(user);
}
}
在这个Controller中,我们添加了两个接口:获取用户信息和创建用户信息。当我们访问/users/{id}接口时,可能会出现资源不存在的异常。为了处理这个问题,我们抛出了ResourceNotFoundException异常。
接下来,我们需要测试一下这个接口,代码如下:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetUserWithNonexistentId() {
ResponseEntity<ErrorDetails> response = restTemplate.getForEntity("/users/1", ErrorDetails.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
assertThat(response.getBody().getMessage()).isEqualTo("User not found with id 1");
}
}
在这个测试用例中,我们使用了SpringBoot的TestRestTemplate,访问了我们的/users/1接口,并期望返回HTTP状态码404和"User not found with id 1"错误信息。
示例2
假设我们的应用程序中,存在一个名为User类,代码如下:
public class User {
@NotNull(message = "Name cannot be null")
private String name;
@Min(value = 18, message = "Age should not less than 18")
private int age;
// getters and setters
}
在这个类中,我们添加了相应的注解,用于校验用户输入的信息是否符合要求。当我们访问/users接口时,可能会出现方法参数不合法的异常。为了处理这个问题,我们抛出了MethodArgumentNotValidException异常。
接下来,我们需要测试一下这个接口,代码如下:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testCreateUserWithInvalidAge() {
User invalidUser = new User();
invalidUser.setName("Tom");
invalidUser.setAge(17);
ResponseEntity<ErrorDetails> response = restTemplate.postForEntity("/users", invalidUser, ErrorDetails.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
assertThat(response.getBody().getMessage()).isEqualTo("Age should not less than 18");
}
}
在这个测试用例中,我们创建了一个不符合要求的User对象,并访问了我们的/users接口,并期望返回HTTP状态码400和"Age should not less than 18"错误信息。
总结
通过上述步骤,我们可以非常方便地实现自定义异常处理页面的功能。SpringBoot提供了非常好用的@ControllerAdvice注解和@ExceptionHandler注解,让我们可以统一处理应用程序中的异常,并且返回给用户友好的错误提示信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot详解实现自定义异常处理页面方法 - Python技术站