返回

SpringBoot:轻松搞定全局异常处理+错误码枚举+JSR303校验

后端

SpringBoot实战:全局异常处理+错误码枚举+JSR303校验

1. 全局异常处理的必要性

在SpringBoot项目中,如果不进行全局异常处理,一旦业务层或控制器中发生异常,系统将直接抛出500错误页面,这对用户体验和项目维护都十分不利。

2. SpringBoot全局异常处理

为了解决上述问题,我们需要在SpringBoot项目中添加全局异常处理功能。具体步骤如下:

  • 创建一个新的类来处理异常,如GlobalExceptionHandler
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> handleException(Exception ex, HttpServletRequest request) {
        // 异常处理逻辑
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage());
    }
}
  • 在SpringBoot启动类上添加@ControllerAdvice注解并注册为Spring Bean:
@SpringBootApplication
@ControllerAdvice
public class Application {

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

3. 错误码枚举

在实际开发中,我们经常需要返回特定的错误码以标识不同的异常类型。因此,我们可以创建一个错误码枚举类,如ErrorCodeEnum

public enum ErrorCodeEnum {

    PARAM_ERROR(1001, "参数错误"),
    RESOURCE_NOT_FOUND(1002, "资源不存在"),
    PERMISSION_DENIED(1003, "权限不足");

    private int code;
    private String message;

    ErrorCodeEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

4. SpringBoot JSR303校验

SpringBoot支持JSR303校验,我们可以使用它来对请求参数进行校验。步骤如下:

  • 在实体类上添加JSR303校验注解,如@NotNull@Size@Pattern等:
public class User {

    @NotNull
    private String name;

    @Size(min = 6, max = 18)
    private String password;

    @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+
public class User {

    @NotNull
    private String name;

    @Size(min = 6, max = 18)
    private String password;

    @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")
    private String email;
}
quot;
) private String email; }
  • 在控制器方法上添加@Valid注解,Spring会自动对请求参数进行校验:
@PostMapping("/register")
public String register(@Valid User user) {
    // 处理注册逻辑
}

示例代码

// User.java
public class User {

    @NotNull
    private String name;

    @Size(min = 6, max = 18)
    private String password;

    @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+
// User.java
public class User {

    @NotNull
    private String name;

    @Size(min = 6, max = 18)
    private String password;

    @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")
    private String email;
}

// GlobalExceptionHandler.java
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> handleException(Exception ex, HttpServletRequest request) {
        if (ex instanceof BusinessException) {
            BusinessException businessException = (BusinessException) ex;
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorCodeEnum.PARAM_ERROR);
        } else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorCodeEnum.INTERNAL_SERVER_ERROR);
        }
    }
}

// UserController.java
@RestController
public class UserController {

    @PostMapping("/register")
    public String register(@Valid User user) {
        // 处理注册逻辑
        return "注册成功";
    }
}
quot;
)
private String email; } // GlobalExceptionHandler.java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<Object> handleException(Exception ex, HttpServletRequest request) { if (ex instanceof BusinessException) { BusinessException businessException = (BusinessException) ex; return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorCodeEnum.PARAM_ERROR); } else { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorCodeEnum.INTERNAL_SERVER_ERROR); } } } // UserController.java @RestController public class UserController { @PostMapping("/register") public String register(@Valid User user) { // 处理注册逻辑 return "注册成功"; } }

结论

通过以上步骤,我们可以实现SpringBoot的全局异常处理、错误码枚举和JSR303校验功能。这可以有效提升系统稳定性和代码健壮性,同时也为后续维护和扩展提供良好的基础。

常见问题解答

  1. 为什么要使用错误码枚举?

错误码枚举可以统一管理错误类型,方便识别和处理不同的异常情况,提高代码的可读性和可维护性。

  1. JSR303校验的作用是什么?

JSR303校验可以帮助我们在请求参数校验阶段就发现问题,避免错误数据进入系统,从而提高数据的准确性和完整性。

  1. 全局异常处理可以捕获所有异常吗?

全局异常处理可以捕获大多数异常,但对于某些系统级异常(如内存溢出、栈溢出等)则无法捕获。

  1. 如何自定义错误信息?

可以在GlobalExceptionHandler中根据异常类型返回不同的错误信息,也可以使用自定义的Exception类抛出异常并返回自定义信息。

  1. 是否需要在所有控制器方法上都添加@Valid注解?

如果需要对控制器方法中的请求参数进行校验,则需要添加@Valid注解。