springmvc 参数校验

  • 在 Web 应用三层架构体系中,表述层负责接收浏览器提交的数据,我们需要在表述层对数据进行检查,将错误的数据隔绝在业务逻辑层之外。

校验概述

  • JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 标准中。
  • JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。
注解 规则
@Null 标注值必须为 null
@NotNull 标注值不可为 null
@AssertTrue 标注值必须为 true
@AssertFalse 标注值必须为 false
@Min(value) 标注值必须大于或等于 value
@Max(value) 标注值必须小于或等于 value
@DecimalMin(value) 标注值必须大于或等于 value
@DecimalMax(value) 标注值必须小于或等于 value
@Size(max,min) 标注值大小必须在 max 和 min 限定的范围内
@Digits(integer,fratction) 标注值值必须是一个数字,且必须在可接受的范围内
@Past 标注值只能用于日期型,且必须是过去的日期
@Future 标注值只能用于日期型,且必须是将来的日期
@Pattern(value) 标注值必须符合指定的正则表达式
  • JSR 303 只是一套标准,需要提供其实现才可以使用。
  • Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
注解 规则
@Email 标注值必须是格式正确的 Email 地址
@Length 标注值字符串大小必须在指定的范围内
@NotEmpty 标注值字符串不能是空字符串
@Range 标注值必须在指定的范围内
  • Spring 4.0 版本已经拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架。

  • Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。

  • 在SpringMVC 中,可直接通过注解驱动 @EnableWebMvc 的方式进行数据校验。

  • Spring 的 LocalValidatorFactoryBean 既实现了 Spring 的 Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在Spring容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean中。

  • Spring本身并没有提供JSR 303的实现,所以必须将JSR 303的实现者的jar包放到类路径下。

  • 配置 @EnableWebMvc后,SpringMVC 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注 @Validated 注解即可让 SpringMVC 在完成数据绑定后执行数据校验的工作。

需要的依赖

xml 复制代码
<!-- 校验注解 -->
<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-web-api</artifactId>
    <version>9.1.0</version>
    <scope>provided</scope>
</dependency>
        
<!-- 校验注解实现-->        
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>8.0.0.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator-annotation-processor</artifactId>
    <version>8.0.0.Final</version>
</dependency>

实体类

java 复制代码
package com.cool.pojo;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Past;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import java.util.Date;

/**
 * name:不为null、不为空字符串
 *      字符串不为空:@NotBlank
 *      集合不为空:@NotEmpty
 *      包装类型不为空:@NotNull
 *
 * password:长度大于6
 */

@Data
public class User {

    @NotBlank
    private String name;

    @Length(min = 6, max = 20)
    private String password;

    @Min(1)
    private int age;

    @Email
    private String email;

    @Past
    private Date birthday;
}

controller

java 复制代码
package com.cool.controller;

import com.cool.pojo.User;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("user")
public class UserController {

    /**
     * 步骤1:实体类属性添加校验注解
     * 步骤2:handler(@Validated 实体类对象){}
     *       细节:
     *          param、json 校验注解都有效果
     *          只不过,json参数的话,需要用 @RequestBody 修饰形参哦!
     *
     * 这里有个天坑:如果不符合校验规则,会直接向前端抛出异常
     * 解决办法:
     *      handler(@Validated 实体类对象, BindingResult request){}
     *      多加一个 BindingResult request 参数,
     *      此参数,必须紧挨着 @Validated 实体类对象,否则此参数不管用
     */
    @PostMapping("register")
    public Object register(@Validated @RequestBody User user, BindingResult result){
        System.out.println("user= " +  user);

        if(result.hasErrors()){
            // 有错误的话,就不直接返回给前端了,可以在这里自定义内容,返回给前端
            Map data = new HashMap();
            data.put("code", 400);
            data.put("msg", "参数校验异常");
            return data;
        }

        return user;
    }
}
相关推荐
shehuiyuelaiyuehao2 小时前
String的杂七杂八方法
java·开发语言
木井巳2 小时前
【递归算法】计算布尔二叉树的值
java·算法·leetcode·深度优先
2 小时前
java关于时间类
java·开发语言
老蒋每日coding2 小时前
FISCO BCOS 部署Solidity投票智能合约并基于Java SDK 调用智能合约详细指南
java·区块链·智能合约
java1234_小锋2 小时前
Spring里AutoWired与Resource区别?
java·后端·spring
风象南2 小时前
Spring Boot 定时任务多实例互斥执行
java·spring boot·后端
崎岖Qiu2 小时前
【深度剖析】:结合 Spring Bean 的生命周期理解 @PostConstruct 的原理
java·笔记·后端·spring·javaee
毕设源码-郭学长2 小时前
【开题答辩全过程】以 基于Springboot旅游景点管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
是三好2 小时前
JUC并发编程
java·开发语言