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等,就会看到参数校验失败的提示信息。

阅读剩余 77%

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

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

相关文章

  • springboot返回modelandview页面的实例

    首先,我们需要了解什么是 Spring Boot。Spring Boot 是 Spring 家族开源的轻量级 Web 开发框架,它简化了 Spring 繁琐的配置,使开发者能够更加专注于业务逻辑的实现。 在 Spring Boot 中,我们可以通过创建一个控制器类来处理请求并返回响应,其中返回 ModelAndView 类型的对象可以用于处理页面渲染。 以下…

    Java 2023年6月15日
    00
  • JavaSpringBoot报错“BeanInstantiationException”的原因和处理方法

    原因 “BeanInstantiationException” 错误通常是以下原因引起的: 没有默认构造函数:如果您的 Bean 没有默认构造函数,则可能会出现此错误。在这种情况下,您需要添加一个默认构造函数。 构造函数参数不正确:如果您的 Bean 构造函数参数不正确,则可能会出现此错误。在这种情况下,您需要检查您的构造函数参数并确保它们正确。 解决办法 …

    Java 2023年5月4日
    00
  • springboot整合redis修改分区的操作流程

    下面是关于“springboot整合redis修改分区的操作流程”的完整攻略: 操作流程 修改redis.conf文件 在redis.conf配置文件中搜索”hash-max-ziplist-entries”和“hash-max-ziplist-value”两个参数。这两个参数决定了Redis使用ziplist存储hash类型的数据结构时,ziplist中的…

    Java 2023年5月20日
    00
  • Java完美实现2048小游戏

    Java完美实现2048小游戏攻略 游戏说明 2048是一款益智类小游戏,玩家需要通过上下左右滑动操作,使得相同数字的方块叠加,最终得到2048这个数字的方块。 Java实现方式 Java可以使用Java Swing组件来实现2048小游戏。在Java Swing中,使用JFrame作为主窗口,使用JPanel作为游戏区域,使用JLabel作为每个数字格子的…

    Java 2023年5月19日
    00
  • asp.net开发微信公众平台之获取用户消息并处理

    我非常愿意为您讲解“asp.net开发微信公众平台之获取用户消息并处理”的完整攻略。 前置条件 在进行下面的步骤之前,您需要准备好以下前置条件: 一个搭建好的asp.net项目。 一个微信公众号。 在微信公众平台上获取到公众号的AppID和AppSecret。 安装WeChat SDK。 步骤1:获取微信服务器发送的消息 通过ASP.NET处理微信公众平台的…

    Java 2023年5月19日
    00
  • Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍

    针对“Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍”的话题,以下是完整攻略的介绍: 一、概述 OpenSSL是一个开源的安全套接字层(SSL)实现库,能够实现多种安全协议,包括SSL和TLS。Java OpenSSL是使用Java编写的,利用OpenSSL库生成RSA公私钥,以及使用公私钥进行数据的加解密。 本文将详细介绍Java Ope…

    Java 2023年5月19日
    00
  • Java中关于char类型变量能够输出中文的问题

    Java中的char类型变量能够输出中文,是因为Java使用的是Unicode字符编码标准,其中全球所有的字符都有唯一的码位,包括中文字符。在Java中,char类型变量以16位无符号整数形式存储字符。由于Unicode字符集在编码范围内包含了中文字符,所以Java的char类型变量和String类型能将中文字符完美输出。 在Java中,对于char类型变量…

    Java 2023年5月26日
    00
  • JSP如何获取客户端真实IP地址

    获取客户端真实IP地址是JSP开发中的一个常见问题。由于客户端的IP地址可以被篡改,因此需要采取一些技巧来获取真实的IP地址。 以下是获取客户端真实IP地址的完整攻略: 方法一:使用request对象获取 JSP中可以通过request对象获取客户端IP地址,具体步骤如下: <% String ipAddress = request.getHeader…

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