自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

異常奇談 - 揭示全局異常處理的神秘面紗

開發(fā) 前端
通過今天的學(xué)習(xí),我們成功踏上了全局異常處理的探索之旅,為提升系統(tǒng)的穩(wěn)定性和用戶體驗(yàn)打下了堅(jiān)實(shí)的基礎(chǔ)。通過建立全局異常處理器,我們能夠更加靈活地捕獲和處理應(yīng)用程序中各種異常,從而提供更友好、更有針對性的錯(cuò)誤信息。

在今天的學(xué)習(xí)中,我們深入研究了全局異常處理,以提升系統(tǒng)的穩(wěn)定性和用戶體驗(yàn)。通過建立全局異常處理器,我們能夠捕獲和處理應(yīng)用程序中產(chǎn)生的各種異常,并向前端返回更加友好的錯(cuò)誤信息。接下來,我們將詳細(xì)介紹一些常用的全局異常處理注解,同時(shí)提供相應(yīng)的示例代碼,幫助您更好地理解和應(yīng)用這些異常處理機(jī)制。

在 Spring Boot 中,通過使用 @ControllerAdvice 注解結(jié)合不同的注解,我們可以實(shí)現(xiàn)全局異常的處理。以下是一些常用的全局異常注解的詳細(xì)介紹及示例代碼:

@ControllerAdvice
  • 作用: 聲明一個(gè)類為全局控制器增強(qiáng)類,用于集中處理異常。
  • 位置: 通常放在類的頂部,作為一個(gè)全局異常處理器的聲明。
  • 示例代碼:
@ControllerAdvice
public class GlobalExceptionHandler {
    // ...
}
@ExceptionHandler
  • 作用: 用于標(biāo)識方法為異常處理方法,處理特定類型的異常。
  • 位置: 可以放在類級別的 @ControllerAdvice 下,也可以放在普通的 Controller 類中。
  • 示例代碼:
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body("An unexpected error occurred: " + e.getMessage());
}
@ResponseStatus
  • 作用: 指定異常發(fā)生時(shí)返回的 HTTP 狀態(tài)碼。
  • 位置: 可以標(biāo)注在異常處理方法上,也可以標(biāo)注在自定義異常類上。
  • 示例代碼:
@ExceptionHandler(CustomException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<String> handleCustomException(CustomException e) {
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Custom exception: " + e.getMessage());
}
@RestControllerAdvice
  • 作用: 類似于 @ControllerAdvice,但用于 RESTful 接口的異常處理。
  • 位置: 通常放在類的頂部,作為一個(gè)全局異常處理器的聲明。
  • 示例代碼:
@RestControllerAdvice
public class RestExceptionHandler {
    // ...
}
@Validated 和 @Valid
  • 作用: 用于參數(shù)校驗(yàn),通常用于在 Controller 層進(jìn)行入?yún)⑿r?yàn)。
  • 位置: 可以標(biāo)注在方法參數(shù)上,也可以標(biāo)注在類的字段上。
  • 示例代碼:
@PostMapping("/create")
public ResponseEntity<String> createUser(@Validated @RequestBody User user) {
    // 處理用戶創(chuàng)建邏輯
    return ResponseEntity.ok("用戶創(chuàng)建成功");
}

以上是一些常用的全局異常處理注解及參數(shù)校驗(yàn)注解的詳細(xì)介紹及示例代碼。通過合理使用這些注解,可以使全局異常處理更加靈活和規(guī)范。

讓我們開始全局異常處理的探索之旅吧,共同深入研究如何提升系統(tǒng)的穩(wěn)定性和用戶體驗(yàn)。通過建立全局異常處理器,我們將能夠捕獲并處理應(yīng)用程序中產(chǎn)生的各種異常,并向前端返回更加友好的錯(cuò)誤信息。

創(chuàng)建 Day 8 子模塊

首先,進(jìn)入項(xiàng)目根目錄:

cd springboot60days

創(chuàng)建 Day 8 子模塊:

mkdir day8-global-exception
cd day8-global-exception

在 Day 7 子模塊的基礎(chǔ)上,創(chuàng)建 Day 8 子模塊。在父模塊的 pom.xml 中添加 Day 8 子模塊的配置:

<!-- springboot60days/pom.xml -->
<modules>
    <module>day4-database-magic</module>
    <module>day5-mybatis-mystery</module>
    <module>day6-mybatis-plus-journey</module>
    <module>day7-data-validation</module>
    <module>day8-global-exception</module>
</modules>
子模塊 pom.xml 配置
<!-- day8-global-exception/pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
          <groupId>com.icoderoad.springboot60days</groupId>
          <artifactId>springboot60days</artifactId>
          <version>1.0-SNAPSHOT</version>
      </parent>

  <artifactId>day8-global-exception</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>

      <!-- Lombok依賴 -->
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <optional>true</optional>
      </dependency>

      <!-- Spring Boot Starter Web (Assuming you need web support) -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

      <!-- Spring Boot Starter -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
      </dependency>

      <!-- MyBatis-Plus Starter -->
      <dependency>
          <groupId>com.baomidou</groupId>
          <artifactId>mybatis-plus-boot-starter</artifactId>
          <version>3.5.4.1</version>
      </dependency>

       <!-- Spring Boot Starter Validation -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-validation</artifactId>
      </dependency>
    
      <!-- H2 Database (for testing) -->
      <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <scope>runtime</scope>
      </dependency>
  </dependencies>

  <build>
      <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
      </plugins>
  </build>

</project>
創(chuàng)建配置文件:

在 src/main/resources 目錄下創(chuàng)建 application.properties :

# springboot60days/day8-global-exception/src/main/resources/application.properties

# Spring Boot 應(yīng)用程序名稱
spring.application.name=day8-global-exception

# 數(shù)據(jù)庫配置
spring.datasource.url=jdbc:h2:mem:userdb;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true

# MyBatis-Plus 配置
mybatis-plus.mapper-locations=classpath:mapper/*.xml

# 分頁插件配置
mybatis-plus.configuration.plugins=com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
mybatis-plus.configuration.plugins.pagination.type=com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
全局異常處理器 GlobalExceptionHandler.java
// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/exception/GlobalExceptionHandler.java
package com.icoderoad.springboot60days.day8.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;
import java.util.stream.Collectors;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("An unexpected error occurred: " + e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        String errorMessage = fieldErrors.stream()
                .map(fieldError -> fieldError.getField() + ": " + fieldError.getDefaultMessage())
                .collect(Collectors.joining(", "));
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorMessage);
    }

    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleBindingException(BindException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        String errorMessage = fieldErrors.stream()
                .map(fieldError -> fieldError.getField() + ": " + fieldError.getDefaultMessage())
                .collect(Collectors.joining(", "));
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorMessage);
    }
}
編寫實(shí)體類

創(chuàng)建一個(gè)具有年齡和郵箱屬性的用戶實(shí)體類 User,并在該屬性上添加 Validation 注解,進(jìn)行最大值、最小值和郵箱格式的驗(yàn)證。

// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/entity/User.java
package com.icoderoad.springboot60days.day8.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;

@Data
@TableName(value = "my_user")
public class User {

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @NotBlank(message = "用戶名不能為空")
    private String username;

    @Max(value = 60, message = "年齡不能大于60歲")
    @Min(value = 18, message = "年齡不能小于18歲")
    private Integer age;

    @Email(message = "郵箱格式不正確")
    private String email;

}
Mapper 接口 UserMapper.java
// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/mapper/UserMapper.java
package com.icoderoad.springboot60days.day8.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.icoderoad.springboot60days.day8.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}
編寫 MyBatis-Plus Service 接口及實(shí)現(xiàn)類

創(chuàng)建一個(gè) MyBatis-Plus Service 接口 UserService 和其實(shí)現(xiàn)類 UserServiceImpl,用于處理與數(shù)據(jù)庫的交互。

UserService.java

// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/service/UserService.java
package com.icoderoad.springboot60days.day8.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.icoderoad.springboot60days.day8.entity.User;

public interface UserService extends IService<User> {
    // 可以添加自定義業(yè)務(wù)方法...
}

UserServiceImpl.java

// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/service/impl/UserServiceImpl.java
package com.icoderoad.springboot60days.day8.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icoderoad.springboot60days.day8.entity.User;
import com.icoderoad.springboot60days.day8.mapper.UserMapper;
import com.icoderoad.springboot60days.day8.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 可以添加自定義業(yè)務(wù)方法...
}
編寫控制器 UserController

更新 UserController 類,調(diào)用 MyBatis-Plus Service 接口處理用戶的 CRUD 操作。

// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/controller/UserController.java
package com.icoderoad.springboot60days.day8.controller;

import com.icoderoad.springboot60days.day8.entity.User;
import com.icoderoad.springboot60days.day8.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

import java.util.List;

@RestController
@RequestMapping("/users")
@Validated
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.list();
        return new ResponseEntity<>(users, HttpStatus.OK);
    }

    @PostMapping
    public String createUser(@Valid @RequestBody User user) {
        userService.save(user);
        return "用戶創(chuàng)建成功!";
    }

    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getById(id);
    }

    @PutMapping("/{id}")
    public String updateUser(@PathVariable Long id, @Valid @RequestBody User user) {
        user.setId(id);
        userService.updateById(user);
        return "用戶更新成功!";
    }

    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable Long id) {
        userService.removeById(id);
        return "用戶刪除成功!";
    }
}
初始化類 DatabaseInitializer
// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/init/DatabaseInitializer.java
package com.icoderoad.springboot60days.day8.init;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.jdbc.core.JdbcTemplate;

@Component
public class DatabaseInitializer implements CommandLineRunner {

    private final JdbcTemplate jdbcTemplate;

    public DatabaseInitializer(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void run(String... args) throws Exception {
        // 初始化數(shù)據(jù)庫表
        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS my_user (" +
                "id INT AUTO_INCREMENT PRIMARY KEY," +
                "username VARCHAR(255)," +
                "email VARCHAR(255)," +
                "age INT" +
                ")");
    }
}
配置類 MyBatisPlusConfig.java
// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/config/MyBatisPlusConfig.java
package com.icoderoad.springboot60days.day8.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan({"com.icoderoad.springboot60days.day8.mapper"})
public class MyBatisPlusConfig {

    /**
     * 分頁插件,自動(dòng)識別數(shù)據(jù)庫類型
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
創(chuàng)建啟動(dòng)類 Day8GlobalExceptionApplication.java:
// springboot60days/day8-global-exception/src/main/java/com/icoderoad/springboot60days/day8/Day8GlobalExceptionApplication.java
package com.icoderoad.springboot60days.day8;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Day8GlobalExceptionApplication {

    public static void main(String[] args) {
        SpringApplication.run(Day8GlobalExceptionApplication.class, args);
    }

}

Mapper 文件 UserMapper.xml

<!--springboot60days/day8-global-exception/src/main/java/resource/mapper/UserMapper.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.icoderoad.springboot60days.day8.mapper.UserMapper">
      <resultMap id="userResultMap" type="com.icoderoad.springboot60days.day8.entity.User">
          <id column="id" property="id"/>
          <result column="username" property="username"/>
          <result column="email" property="email"/>
          <result column="age" property="age"/>
          <!-- 其他字段 -->
      </resultMap>

  </mapper>
啟動(dòng)應(yīng)用程序:

在 day8-global-exception 子模塊的根目錄下,執(zhí)行以下命令啟動(dòng) Spring Boot 應(yīng)用程序:

mvn spring-boot:run
測試功能實(shí)現(xiàn)

在 Apifox 或 Postman 中,你可以使用以下命令測試 RESTful API 的增、刪、改、查操作:

獲取所有用戶信息(GET請求)

  • 請求URL:http://localhost:8080/users
  • 請求方式:GET

創(chuàng)建用戶(POST請求)

  • 請求URL:http://localhost:8080/users
  • 請求方式:POST
  • 請求體:
{
  "username": "icoderoad",
  "age": 25,
  "email": "icoderoad@example.com"
}

更新用戶信息(PUT請求)

  • 請求URL:http://localhost:8080/users/{userId}
  • 請求方式:PUT
  • 請求體:
{
  "username": "newUsername",
  "age": 26,
  "email": "newEmail@example.com"
}

刪除用戶(DELETE請求)

  • 請求URL:http://localhost:8080/users/{userId}
  • 請求方式:DELETE

測試異常處理 - 數(shù)據(jù)校驗(yàn)失?。≒OST請求)

  • 請求URL:http://localhost:8080/users
  • 請求方式:POST
  • 請求體:
{
  "username": "icoderoad",
  "age": 15,  // 年齡小于最小值
  "email": "icoderoad@example.com"
}

測試異常處理 - 數(shù)據(jù)校驗(yàn)失?。≒UT請求)

  • 請求URL:http://localhost:8080/users/{userId}
  • 請求方式:PUT
  • 請求體:
{
  "username": "newUsername",
  "age": 8,  // 年齡小于最小值
  "email": "newEmail@example.com"
}

測試異常處理 - 數(shù)據(jù)校驗(yàn)失?。℅ET請求,ID為負(fù)數(shù))

  • 請求URL:http://localhost:8080/users/-1
  • 請求方式:GET

以上測試用例覆蓋了正常的 CRUD 操作以及異常處理情況,確保全局異常處理器能夠返回友好的錯(cuò)誤信息。

通過今天的學(xué)習(xí),我們成功踏上了全局異常處理的探索之旅,為提升系統(tǒng)的穩(wěn)定性和用戶體驗(yàn)打下了堅(jiān)實(shí)的基礎(chǔ)。通過建立全局異常處理器,我們能夠更加靈活地捕獲和處理應(yīng)用程序中各種異常,從而提供更友好、更有針對性的錯(cuò)誤信息。在這一過程中,我們深入了解了一系列常用的全局異常處理注解,并通過詳細(xì)的示例代碼展示了它們的應(yīng)用方式,為今后更加自信地應(yīng)對異常情況奠定了基礎(chǔ)。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2010-03-31 09:17:59

2019-01-24 16:11:19

前端全局異常數(shù)據(jù)校驗(yàn)

2022-03-04 08:31:07

Spring異常處理

2017-08-10 10:28:43

SpringBootSpring

2009-02-06 14:11:36

ASP.NET.NET全局異常處理

2021-04-20 10:50:38

Spring Boot代碼Java

2015-08-20 13:43:17

NFV網(wǎng)絡(luò)功能虛擬化

2023-12-11 14:19:00

Java程序異常

2013-08-22 17:10:09

.Net異常處理

2012-12-21 10:48:20

Java異常

2012-11-12 10:32:48

IBMdw

2018-07-11 19:41:47

MySQL定義異常異常處理

2018-08-20 16:25:48

編程語言Java異常處理

2010-05-17 09:13:35

2014-03-12 11:11:39

Storage vMo虛擬機(jī)

2021-06-07 08:18:12

云計(jì)算云端阿里云

2011-11-18 09:26:18

Javafinally

2022-12-28 08:17:19

異常處理code

2010-05-26 19:12:41

SVN沖突

2009-07-17 17:34:03

SwingWorker異常處理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號