SpringBoot详解实现自定义异常处理页面方法

下面是关于“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技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • java初学者必须理解这几个问题

    Java初学者必须理解这几个问题攻略 Java是目前应用最为广泛的编程语言之一,也是很多程序员的首选语言。但对于初学者来说,Java的庞大框架和语法结构,往往会带来不少难题。以下是初学者在学习Java过程中必须理解的几个问题。 1. 面向对象编程 Java是一种面向对象的编程语言,理解面向对象的思想是学习Java的第一步。面向对象编程,将数据与操作封装在一个…

    Java 2023年5月27日
    00
  • 详解Springboot2.3集成Spring security 框架(原生集成)

    我来为你详细讲解“详解Springboot2.3集成Spring security框架(原生集成)”的完整攻略。 1. 简介 Spring Security是Spring Framework的一个安全框架,为Spring应用程序提供综合的认证(Authentication)和授权(Authorization)解决方案。这个框架提供了一种方式来将应用程序的用户…

    Java 2023年5月20日
    00
  • 红旗Linux4.1下安装配置Apahce+Tomcat+PHP+mySQL+vsFTPd

    下面是在红旗Linux 4.1系统下安装、配置Apache、Tomcat、PHP、MySQL和vsftpd的攻略步骤: 准备工作 安装并正确配置好红旗Linux 4.1系统,获取root权限 确保网络连接正常,可以访问外部网络 确认系统中已经安装了C/C++编译器,以及一些常用的开发工具和库文件 安装Apache 下载最新版本的Apache,使用wget命令…

    Java 2023年5月19日
    00
  • Spring中使用atomikos+druid实现经典分布式事务的方法

    Spring是一个非常流行的Java框架,可以用于构建各种类型的应用程序,包括分布式应用程序。在分布式应用程序中,经典的分布式事务是非常重要的,它可以确保整个事务的一致性和完整性。Atomikos和Druid是常用的分布式事务解决方案,它们都有很多优点,例如可靠性、高性能和灵活性等。下面是如何在Spring中使用Atomikos和Druid实现经典分布式事务…

    Java 2023年5月20日
    00
  • Java经典面试题汇总:JVM

    Java经典面试题汇总:JVM JVM是什么? JVM(Java Virtual Machine,即Java虚拟机)是Java平台的一个重要组成部分,也是整个Java技术体系的核心所在。它是Java实现“一次编写,到处运行”的重要基石,同时也是Java能够拥有强大的跨平台能力的主要原因之一。 当我们运行Java程序时,JVM会解释并执行Java字节码,最终把…

    Java 2023年5月23日
    00
  • php基于环形链表解决约瑟夫环问题示例

    PHP基于环形链表解决约瑟夫环问题 什么是约瑟夫环问题? 约瑟夫环问题是一个有名的问题:N个人围成一圈,从第K个人开始报数,第M个人出圈;以此类推,直到所有人出圈。这个问题可以用链表来解决。 解决约瑟夫环问题的关键 解决约瑟夫环问题的关键是构建一个循环链表,从链表的头开始,每m个节点删除一个节点,直到链表中只剩一个节点,这个节点就是最后的幸存者。 PHP实现…

    Java 2023年5月26日
    00
  • java文件操作工具类实现复制文件和文件合并

    针对这个问题,我会从以下几个方面进行讲解: Java文件操作的基础知识 复制文件的实现方法 合并文件的实现方法 工具类的封装实现 两条示例 1. Java文件操作的基础知识 在Java中,文件的读写操作通常使用IO流来进行。Java提供了两种类型的IO流:字节流和字符流。其中字节流可以处理所有类型的文件,而字符流只能处理文本文件。因此,在文件复制和合并操作中…

    Java 2023年5月20日
    00
  • Spring如何集成ibatis项目并实现dao层基类封装

    下面就是详细讲解“Spring如何集成ibatis项目并实现dao层基类封装”的完整攻略。 目录 Spring和iBatis的集成 示例一:使用iBatis进行单表操作 示例二:使用iBatis进行多表操作 Dao层基类封装 Spring和iBatis的集成 Spring和iBatis的集成需要以下几个步骤: 引入Spring和iBatis相关的jar包 配…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部