SpringBoot参数校验之@Valid的使用详解

SpringBoot参数校验之@Valid的使用详解

在Spring Boot中,参数校验是非常重要的一环,在实际开发中,我们经常会遇到需要对用户提交的数据进行校验的场景,比如注册时,我们需要校验用户名、密码、邮箱格式等数据是否符合要求。这时,我们就可以通过使用Spring Boot提供的参数校验功能来实现。

Spring Boot提供了一个非常方便的参数校验工具——Java Bean Validation,通过注解、API等方式可以方便地对Java Bean对象属性的有效性进行校验。其中,最为常用的注解就是@Valid注解。

@Valid注解的作用

@Valid注解表示需要对被注解的对象进行校验,通常用在Controller层的方法参数上。

如何使用@Valid注解实现参数校验

在使用@Valid注解进行参数校验之前,需要先引入相关依赖,依赖的配置如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

当引入了上述的依赖后,就可以在Controller层的方法参数上使用@Valid注解进行参数校验了。例如:

@PostMapping("/register")
public String register(@Valid User user) {
    // do something
}

在上述的例子中,@Valid注解被用来校验User对象,如果User对象中的某些属性不合法,那么在校验时就会抛出MethodArgumentNotValidException异常。

同时在实际使用中,还需要在User对象的相应属性上加上校验注解,例如:@NotNull、@Size等。示例:

public class User {
    @NotNull(message = "用户名不能为空")
    private String userName;

    @NotNull(message = "密码不能为空")
    @Size(min = 6, max = 16, message = "密码长度必须在6~16之间")
    private String password;

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

    // getter/setter方法...
}

在上述的例子中,@NotNull注解表示userName和password属性的值不能为空,@Size注解表示password属性的值长度必须在6~16之间,@Email注解表示email属性的值必须是一个符合邮箱格式要求的字符串。

多参数校验

在实际开发中,我们可能需要校验多个参数,此时可以使用嵌套对象的方式来实现。例如:

public class LoginRequest {
    @NotNull(message = "用户名不能为空")
    private String userName;

    @NotNull(message = "密码不能为空")
    @Size(min = 6, max = 16, message = "密码长度必须在6~16之间")
    private String password;

    // getter/setter方法...
}

@PostMapping("/login")
public String login(@Valid LoginRequest loginRequest) {
    // do something
}

在上述的例子中,LoginRequest对象中包含了userName和password属性,在方法参数上使用@Valid注解表示需要对LoginRequest对象进行校验,并在LoginRequest类的相应属性上再加上其他的校验注解即可。

自定义校验

在实际开发中,我们可能会遇到一些特定的校验需求,此时可以使用自定义校验注解来实现。自定义校验注解十分灵活,能够实现各种各样的校验需求。例如,我们可以自定义一个注解,来表示一个字符串必须是一个由字母、数字和下划线组成的字符串,示例:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {UserNameValidator.class})
public @interface UserName {
    String message() default "用户名必须是字母、数字、下划线";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

public class UserNameValidator implements ConstraintValidator<UserName, String> {

    @Override
    public void initialize(UserName constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        return value.matches("^[A-Za-z0-9_]+$");
    }
}

在上述的例子中,自定义了一个@UserName注解,表示一个字符串必须是一个由字母、数字和下划线组成的字符串。在定义了@UserName注解之后,需要编写一个UserNameValidator类,来实现具体的校验逻辑。

在Controller层中定义全局异常处理器

在使用参数校验时,如果某个参数不合法,就会抛出MethodArgumentNotValidException异常,为了更好地处理这个异常,可以在Controller层中定义一个全局异常处理器。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        StringBuilder builder = new StringBuilder();
        bindingResult.getFieldErrors().forEach(fieldError -> builder.append(fieldError.getDefaultMessage()).append("; "));
        ErrorResponse response = new ErrorResponse("参数校验失败:" + builder.toString());
        return ResponseEntity.badRequest().body(response);
    }
}

在上述的例子中,定义了一个全局异常处理器GlobalExceptionHandler,当抛出MethodArgumentNotValidException异常时,会进入handleMethodArgumentNotValidException方法进行处理。在该方法中,首先获取BindingResult对象,然后获取每一个FieldError对象并拼接错误信息,最后返回一个ErrorResponse对象,表示参数校验失败。

示例

下面我们通过一个完整的示例来演示如何使用@Valid注解实现参数校验。该示例是实现一个注册功能,包含一个注册页面和一个注册接口。

注册页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
<h1>用户注册</h1>
<form action="/register" method="post">
    用户名:<input type="text" name="userName"><br>
    密码:<input type="password" name="password"><br>
    邮箱:<input type="email" name="email"><br>
    <input type="submit" value="注册">
</form>
</body>
</html>

注册接口代码

@PostMapping("/register")
public ResponseEntity<SuccessResponse> register(@Valid User user) {
    userService.register(user.getUserName(), user.getPassword(), user.getEmail());
    return ResponseEntity.ok().body(new SuccessResponse("注册成功"));
}

在该代码中,@Valid注解被用来校验User对象的三个属性:userName、password和email,如果其中任何一个属性的值不合法,就会抛出MethodArgumentNotValidException异常。在实际开发中,我们需要在User类中添加对应的注解,示例:

public class User {
    @NotNull(message = "用户名不能为空")
    private String userName;

    @NotNull(message = "密码不能为空")
    @Size(min = 6, max = 16, message = "密码长度必须在6~16之间")
    private String password;

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

    // getter/setter方法...
}

在该代码中,@NotNull注解表示userName和password属性的值不能为空,@Size注解表示password属性的值长度必须在6~16之间,@Email注解表示email属性的值必须是一个符合邮箱格式要求的字符串。

同时,在Controller层中,我们通过定义一个全局异常处理器GlobalExceptionHandler,来对参数校验时抛出的异常进行统一处理,示例:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        StringBuilder builder = new StringBuilder();
        // 获取每一个错误消息,拼接成一个字符串
        bindingResult.getFieldErrors().forEach(fieldError -> builder.append(fieldError.getDefaultMessage()).append("; "));
        ErrorResponse response = new ErrorResponse("参数校验失败:" + builder.toString());
        return ResponseEntity.badRequest().body(response);
    }
}

在该代码中,我们通过@ControllerAdvice注解来标记该类为全局异常处理器,将handleMethodArgumentNotValidException方法标记为对MethodArgumentNotValidException异常进行处理的方法。在该方法中,我们首先获取BindingResult对象,然后获取每一个FieldError对象并拼接错误信息,最后返回一个ErrorResponse对象,表示参数校验失败。

在运行程序之后,访问注册页面,输入正确的用户名、密码和邮箱,就可以看到注册成功的信息。如果输入不合法的数据,比如用户没有输入用户名,或者输入的密码长度小于6等,就会看到参数校验失败的提示信息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot参数校验之@Valid的使用详解 - Python技术站

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

相关文章

  • 如何在vue项目中嵌入jsp页面的方法(2种)

    在 Vue 项目中嵌入 JSP 页面可以通过以下两种方法实现: 方法一:使用 iframe 标签嵌入 JSP 页面 可以使用 iframe 标签嵌入 JSP 页面,使用方法如下: 在 Vue 组件中使用 iframe 标签,并设置 src 属性为 JSP 页面的地址。 <template> <div class="jsp-page…

    Java 2023年6月15日
    00
  • java实现列表、集合与数组之间转化的方法

    关于Java实现列表、集合与数组间的转化,我们可以采用Java API中提供的相关类库来实现。Java程序员常用的类库主要为java.util包下的ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。 下面,我将详细讲解Java实现列表、集合与数组间的转化的方法。 列表转化为数组 ArrayList -…

    Java 2023年5月26日
    00
  • 在js与java中判断json数据中是否含有某字段的案例

    在 JS 中判断 JSON 数据中是否含有某字段的方法如下: 使用 in 运算符: const jsonData = { name: ‘Tom’, age: 18 }; if (‘name’ in jsonData) { console.log(‘jsonData 存在 name 字段’); } 使用 hasOwnProperty() 方法: const j…

    Java 2023年5月26日
    00
  • java 排序算法之选择排序

    Java 排序算法之选择排序 选择排序(Selection Sort)算法是一种简单直观的排序算法,它的基本思路是在未排序序列中找到最小元素,然后将其存放到序列的起始位置,然后再从剩余未排序的序列中继续寻找最小元素,存放到已排序序列的末尾。以此类推,直到全部元素均排序完成。 排序过程 以从小到大排序为例,选择排序的一次过程如下: 从待排序的序列中,找到关键字…

    Java 2023年5月19日
    00
  • Spring mvc实现Restful返回json格式数据实例详解

    下面是关于“Spring MVC实现Restful返回JSON格式数据实例详解”的完整攻略,包含两个示例说明。 Spring MVC实现Restful返回JSON格式数据 在本文中,我们将介绍如何使用Spring MVC实现Restful返回JSON格式数据。 步骤1:添加依赖 首先,我们需要在pom.xml中添加Spring MVC和Jackson的依赖。…

    Java 2023年5月17日
    00
  • Java线程安全中的单例模式

    Java线程安全的单例模式是一种保证多线程环境中只有一个实例对象的技术,以解决因多线程环境中多个进程对同一对象资源进行并发操作,产生冲突和错误的问题。在Java开发中,单例模式有多种实现方式,如懒汉式、饿汉式、双重检查Lock方式等。本文将针对Java线程安全的单例模式进行详细讲解,为大家提供完整攻略和两条示例说明。 一、Java线程安全中的单例模式 1.懒…

    Java 2023年5月26日
    00
  • Spring Security拦截器引起Java CORS跨域失败的问题及解决

    Spring Security拦截器引起Java CORS跨域失败的问题及解决 在使用Spring Security进行接口保护的时候,经常会遇到因为跨域问题导致前端无法访问服务器接口的问题。本文将详细介绍Spring Security拦截器引起Java CORS跨域失败的问题及解决。 什么是CORS跨域 CORS(Cross-Origin Resource…

    Java 2023年5月20日
    00
  • 解析Java中所有错误和异常的父类java.lang.Throwable

    解析Java中所有错误和异常的父类java.lang.Throwable,可以分为以下两个步骤: 了解Throwable类 Throwable类是Java中所有错误和异常的父类。它有两个直接的子类:Error和Exception。其中,Error表示严重的系统错误,如虚拟机错误、线程死锁等,是无论如何也无法处理的错误,只能让程序退出。而Exception则表…

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