我会详细讲解“详解Spring全局异常处理的三种方式”的完整攻略,并给出两个示例说明。
1. 为什么需要全局异常处理
Spring应用程序在运行过程中难免会遇到一些异常,如异常的输入、网络连接中断等。这些异常无法避免,但我们需要对这些异常进行合理的处理以便程序更健壮。而全局异常处理正是为此而设。
全局异常处理是指在应用程序中捕获所有未被捕获的异常,并尝试对它们进行恰当的处理。它在以下方面提供了价值:
- 避免将异常抛给系统入口,提高应用程序健壮性。
- 可以避免在日志或控制台中看到未处理的异常。
- 可以尝试恢复异常,或向用户提供友好的错误提示。
2. 方式一:使用@ControllerAdvice进行全局异常处理
@ControllerAdvice是Spring提供的异常处理增强器。它允许我们使用一个单独的类来控制对所有异常的统一处理。
首先,我们定义一个ControllerAdvice类,用于处理全局异常:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
// 返回自定义错误信息及状态码
return new ResponseEntity<>("处理错误:" + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
上面的代码中,我们指定了一个全局的Exception处理程序,它处理所有未处理的异常,并输出自定义的错误信息。
接下来,我们编写一个Controller类,它会抛出一个RuntimeException,而我们的全局异常处理程序会捕获它:
@RestController
public class HomeController {
@GetMapping("/")
public String index() {
throw new RuntimeException("测试异常");
}
}
如果你现在向http://localhost:8080/发送一个GET请求,你将会看到如下输出:
处理错误:测试异常
这就是一个最简单的全局异常处理的实现方式。
3. 方式二:使用XML进行全局异常处理
我们也可以使用XML来配置全局异常处理。以下是一个全局异常处理的XML配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">error</prop>
</props>
</property>
</bean>
</beans>
在上面的配置中,我们指定了一个SimpleMappingExceptionResolver程序,用于处理所有Exception异常,并将它们映射到错误页面。
4. 方式三:使用@WebAdvice进行全局异常处理
@WebAdvice是Spring4.3中新引入的一种异常处理方式,它与@ControllerAdvice类似,但更加简单。我们定义一个类并添加@WebAdvice注解,如下所示:
@WebAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex) {
// 返回自定义错误信息及状态码
return new ResponseEntity<>("处理错误:" + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
上述代码中,我们使用@WebAdvice注解注释了一个全局异常处理程序,并对异常进行了捕获和处理。
5. 示例
假设我们有一个Controller,其中包含一些方法,对这些方法抛出的异常进行处理:
@RestController
public class UserController {
@PostMapping("/users")
public ResponseEntity createUser(@RequestBody User user){
// Simulate runtime exception
if(user.getName().equalsIgnoreCase("test")){
throw new RuntimeException("Test Exception");
}
return ResponseEntity.ok("User created successfully");
}
@GetMapping("/users/{id}")
public User getUser(@PathVariable int id){
User user = new User();
// Simulate runtime exception
if(id == 0){
throw new RuntimeException("Invalid User ID");
};
return user;
}
}
如果我们现在尝试使用POST方法创建用户并在创建用户名为test的用户时发生运行时异常,或者通过GET方法获取用户时提供无效的用户ID,会返回一个 server error。 我们需要改进这个行为并以友好的方式通知用户。
我们可以通过使用@ControllerAdvice并实现一个ExceptionHandler来处理这种行为。 下面是代码示例 (我们将重新使用方式1):
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException e) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage(e.getMessage());
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeeksException(Exception e) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage(e.getMessage());
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
在这里,GlobalExceptionHandler类中的方法会捕获与别名相同的所有异常,并以友好的方式通知用户。
我们创建一个实体类ErrorResponse==> 错误响应的格式如下所示:
@Data // 类中默认生成setter和getter方法,此处使用了lombok插件
public class ErrorResponse {
private String message;
private String explanation;
private List<String> details;
}
6. 结论
全局异常处理提供了一种统一处理未处理异常的方法,增加了 Spring 应用程序的健壮性,使得用户获得了更好的体验。在以上示例中,我们使用了多种方式来创建全局异常处理程序。虽然有许多方式可供选择,但我们将选择一个适合我们的解决方案,并尽可能使其简洁明了。
希望以上内容对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Spring全局异常处理的三种方式 - Python技术站