SpringBoot怎么配置全局异常处理器捕获异常

发布时间:2023-04-03 11:49:09 作者:iii
来源:亿速云 阅读:128

SpringBoot怎么配置全局异常处理器捕获异常

在开发Spring Boot应用程序时,异常处理是一个非常重要的环节。良好的异常处理机制不仅能够提高代码的健壮性,还能提升用户体验。Spring Boot提供了多种方式来处理异常,其中全局异常处理器是一种非常有效的方式。本文将详细介绍如何在Spring Boot中配置全局异常处理器来捕获和处理异常。

1. 异常处理的重要性

在应用程序中,异常是不可避免的。无论是由于用户输入错误、网络问题还是系统内部错误,异常都会导致程序无法正常执行。如果没有合适的异常处理机制,这些异常可能会导致应用程序崩溃,给用户带来不好的体验。

通过全局异常处理器,我们可以集中处理应用程序中的所有异常,避免在每个方法中都进行异常处理。这样不仅减少了代码的重复性,还提高了代码的可维护性。

2. Spring Boot中的异常处理机制

Spring Boot提供了多种异常处理机制,包括:

本文将重点介绍如何使用全局异常处理器来捕获和处理异常。

3. 全局异常处理器的实现

3.1 创建全局异常处理器类

首先,我们需要创建一个全局异常处理器类。这个类需要使用@ControllerAdvice注解进行标记,表示它是一个全局异常处理器。然后,我们可以在这个类中使用@ExceptionHandler注解来定义处理特定异常的方法。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> handleGlobalException(Exception ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(BadRequestException.class)
    public ResponseEntity<?> handleBadRequestException(BadRequestException ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
    }
}

在上面的代码中,我们创建了一个GlobalExceptionHandler类,并使用@ControllerAdvice注解标记它。然后,我们定义了三个异常处理方法:

3.2 定义异常类

接下来,我们需要定义一些自定义异常类。这些异常类将用于在应用程序中抛出特定的异常。

public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

public class BadRequestException extends RuntimeException {
    public BadRequestException(String message) {
        super(message);
    }
}

3.3 定义错误详情类

为了返回统一的错误响应,我们可以定义一个错误详情类ErrorDetails

import java.util.Date;

public class ErrorDetails {
    private Date timestamp;
    private String message;
    private String details;

    public ErrorDetails(Date timestamp, String message, String details) {
        this.timestamp = timestamp;
        this.message = message;
        this.details = details;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public String getMessage() {
        return message;
    }

    public String getDetails() {
        return details;
    }
}

3.4 在控制器中抛出异常

现在,我们可以在控制器中抛出这些自定义异常,全局异常处理器将捕获并处理它们。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {

    @GetMapping("/resource/{id}")
    public String getResource(@PathVariable Long id) {
        if (id == 1) {
            return "Resource found";
        } else {
            throw new ResourceNotFoundException("Resource not found with id " + id);
        }
    }

    @GetMapping("/bad-request")
    public String badRequest() {
        throw new BadRequestException("Bad request");
    }
}

在上面的代码中,我们定义了两个端点:

3.5 测试全局异常处理器

现在,我们可以启动应用程序并测试全局异常处理器是否正常工作。

  1. 访问http://localhost:8080/api/resource/1,应该返回"Resource found"
  2. 访问http://localhost:8080/api/resource/2,应该返回404状态码和错误详情。
  3. 访问http://localhost:8080/api/bad-request,应该返回400状态码和错误详情。

4. 处理特定类型的异常

除了处理自定义异常外,全局异常处理器还可以处理特定类型的异常,例如NullPointerExceptionIllegalArgumentException等。

@ExceptionHandler(NullPointerException.class)
public ResponseEntity<?> handleNullPointerException(NullPointerException ex, WebRequest request) {
    ErrorDetails errorDetails = new ErrorDetails(new Date(), "Null pointer exception occurred", request.getDescription(false));
    return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
    ErrorDetails errorDetails = new ErrorDetails(new Date(), "Illegal argument exception occurred", request.getDescription(false));
    return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}

在上面的代码中,我们添加了两个新的异常处理方法,分别处理NullPointerExceptionIllegalArgumentException

5. 处理验证异常

在Spring Boot中,我们经常使用@Valid注解来验证请求参数。如果验证失败,Spring Boot会抛出MethodArgumentNotValidException异常。我们可以通过全局异常处理器来捕获并处理这个异常。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleValidationExceptions(MethodArgumentNotValidException ex, WebRequest request) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));
        ErrorDetails errorDetails = new ErrorDetails(new Date(), "Validation failed", errors.toString());
        return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
    }
}

在上面的代码中,我们定义了一个handleValidationExceptions方法来处理MethodArgumentNotValidException异常。该方法将验证错误信息封装到ErrorDetails对象中,并返回400状态码。

6. 处理未捕获的异常

尽管我们已经定义了许多异常处理方法,但仍然有可能存在未捕获的异常。为了确保所有异常都能被处理,我们可以定义一个通用的异常处理方法。

@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleGlobalException(Exception ex, WebRequest request) {
    ErrorDetails errorDetails = new ErrorDetails(new Date(), "An unexpected error occurred", request.getDescription(false));
    return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}

在上面的代码中,我们定义了一个handleGlobalException方法来处理所有未捕获的异常。该方法返回500状态码和错误详情。

7. 自定义错误页面

除了返回JSON格式的错误响应外,我们还可以自定义错误页面。Spring Boot允许我们通过配置ErrorController来自定义错误页面。

7.1 创建自定义错误页面

首先,我们需要在src/main/resources/templates目录下创建一个自定义错误页面error.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Error</title>
</head>
<body>
    <h1>Error Page</h1>
    <p th:text="${error}">Error message</p>
    <p th:text="${status}">Status code</p>
    <p th:text="${timestamp}">Timestamp</p>
</body>
</html>

7.2 配置自定义错误控制器

接下来,我们需要创建一个自定义错误控制器CustomErrorController

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class CustomErrorController implements ErrorController {

    @RequestMapping("/error")
    public String handleError(HttpServletRequest request) {
        // 获取错误状态码
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        // 获取异常信息
        Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");

        // 将错误信息添加到模型中
        request.setAttribute("error", exception != null ? exception.getMessage() : "Unknown error");
        request.setAttribute("status", statusCode);
        request.setAttribute("timestamp", new Date());

        // 返回自定义错误页面
        return "error";
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}

在上面的代码中,我们创建了一个CustomErrorController类,并实现了ErrorController接口。然后,我们定义了一个handleError方法来处理错误请求,并将错误信息添加到模型中。最后,我们返回自定义错误页面error.html

7.3 测试自定义错误页面

现在,我们可以启动应用程序并测试自定义错误页面是否正常工作。

  1. 访问一个不存在的URL,例如http://localhost:8080/unknown,应该显示自定义错误页面。
  2. 访问一个抛出异常的URL,例如http://localhost:8080/api/bad-request,应该显示自定义错误页面。

8. 总结

通过本文的介绍,我们了解了如何在Spring Boot中配置全局异常处理器来捕获和处理异常。全局异常处理器不仅能够集中处理应用程序中的所有异常,还能提高代码的可维护性和用户体验。我们还介绍了如何处理特定类型的异常、验证异常以及自定义错误页面。

在实际开发中,良好的异常处理机制是保证应用程序稳定性和用户体验的关键。希望本文能够帮助你在Spring Boot项目中更好地处理异常。

推荐阅读:
  1. 如何在SpringBoot项目中使用redis数据库
  2. 怎么在SpringBoot中统一api的返回风格

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot

上一篇:Golang官方中的一致性哈希组件怎么实现

下一篇:Python爬虫之怎么使用BeautifulSoup和Requests抓取网页数据

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》