SpringBoot 全局异常错误页面的示例分析

发布时间:2021-11-10 10:17:46 作者:柒染
来源:亿速云 阅读:127

SpringBoot 全局异常错误页面的示例分析

引言

在Web应用开发中,异常处理是一个非常重要的环节。Spring Boot 提供了强大的异常处理机制,允许开发者通过全局异常处理来统一处理应用中的各种异常。本文将详细分析如何在Spring Boot中实现全局异常处理,并通过示例代码展示如何自定义错误页面。

1. Spring Boot 异常处理机制概述

Spring Boot 提供了多种异常处理方式,包括:

本文将重点介绍全局异常处理和自定义错误页面的实现。

2. 全局异常处理

2.1 使用 @ControllerAdvice@ExceptionHandler

@ControllerAdvice 是一个全局异常处理类,它可以捕获所有Controller中抛出的异常。结合@ExceptionHandler注解,可以针对不同类型的异常进行不同的处理。

示例代码

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
        return new ResponseEntity<>("Resource not found: " + ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

在这个示例中,GlobalExceptionHandler类捕获了所有Exception类型的异常,并返回一个包含错误信息的ResponseEntity。对于ResourceNotFoundException类型的异常,返回404状态码。

2.2 自定义异常类

为了更好地管理异常,我们可以自定义异常类。例如,定义一个ResourceNotFoundException类:

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

在Controller中抛出这个异常:

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

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

2.3 处理特定异常

除了处理所有异常,我们还可以针对特定的异常类型进行处理。例如,处理NullPointerException

@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointerException(NullPointerException ex) {
    return new ResponseEntity<>("Null pointer exception: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}

3. 自定义错误页面

Spring Boot 默认提供了/error路径来处理错误,并返回一个默认的错误页面。我们可以通过自定义ErrorController或使用ErrorAttributes来定制错误页面。

3.1 自定义 ErrorController

通过实现ErrorController接口,我们可以自定义错误处理逻辑。

示例代码

@Controller
public class MyErrorController 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");

        if (statusCode == HttpStatus.NOT_FOUND.value()) {
            return "error-404";
        } else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
            return "error-500";
        } else {
            return "error";
        }
    }

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

在这个示例中,MyErrorController根据不同的HTTP状态码返回不同的错误页面。例如,404错误返回error-404.html,500错误返回error-500.html

3.2 使用 ErrorAttributes

ErrorAttributes接口提供了获取错误信息的便捷方式。我们可以通过实现ErrorAttributes接口来自定义错误信息的获取方式。

示例代码

@Component
public class MyErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
        errorAttributes.put("customAttribute", "This is a custom attribute");
        return errorAttributes;
    }
}

在这个示例中,MyErrorAttributes类继承了DefaultErrorAttributes,并添加了一个自定义属性customAttribute

3.3 自定义错误页面模板

src/main/resources/templates目录下,我们可以创建自定义的错误页面模板。例如,error-404.htmlerror-500.html

error-404.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>404 Not Found</title>
</head>
<body>
    <h1>404 Not Found</h1>
    <p>The requested resource was not found.</p>
</body>
</html>

error-500.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>500 Internal Server Error</title>
</head>
<body>
    <h1>500 Internal Server Error</h1>
    <p>An internal server error occurred.</p>
</body>
</html>

4. 配置全局异常处理

为了确保全局异常处理生效,我们需要在Spring Boot应用中进行一些配置。

4.1 配置 @ControllerAdvice

确保GlobalExceptionHandler类被Spring Boot扫描到。通常,Spring Boot会自动扫描@ControllerAdvice注解的类。

4.2 配置 ErrorController

确保MyErrorController类被Spring Boot扫描到,并且/error路径被正确映射。

4.3 配置 ErrorAttributes

确保MyErrorAttributes类被Spring Boot扫描到,并且自定义的错误属性能够被正确获取。

5. 测试全局异常处理

为了验证全局异常处理是否生效,我们可以编写一些测试用例。

5.1 测试 ResourceNotFoundException

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GlobalExceptionHandlerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testResourceNotFoundException() {
        ResponseEntity<String> response = restTemplate.getForEntity("/api/resource/999", String.class);
        assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
        assertEquals("Resource not found: Resource not found with id 999", response.getBody());
    }
}

5.2 测试 NullPointerException

@Test
public void testNullPointerException() {
    ResponseEntity<String> response = restTemplate.getForEntity("/api/resource/null", String.class);
    assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
    assertEquals("Null pointer exception: null", response.getBody());
}

5.3 测试自定义错误页面

@Test
public void testCustomErrorPage() {
    ResponseEntity<String> response = restTemplate.getForEntity("/nonexistent", String.class);
    assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
    assertTrue(response.getBody().contains("404 Not Found"));
}

6. 总结

通过本文的示例分析,我们了解了如何在Spring Boot中实现全局异常处理和自定义错误页面。全局异常处理可以帮助我们统一管理应用中的异常,提高代码的可维护性和可读性。自定义错误页面则可以提升用户体验,使错误信息更加友好和直观。

在实际开发中,我们可以根据具体需求选择合适的异常处理方式,并结合自定义错误页面来提供更好的用户体验。希望本文的内容能够帮助读者更好地理解和应用Spring Boot中的异常处理机制。

推荐阅读:
  1. SpringBoot 统一异常处理
  2. SpringBoot处理全局异常的示例

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

java ee java thymeleaf

上一篇:怎么使用SICER进行peak calling

下一篇:Django中的unittest应用是什么

相关阅读

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

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