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;
    }
}
相关推荐
c++之路12 小时前
C++20概述
java·开发语言·c++20
Championship.23.2412 小时前
Linux Top 命令族深度解析与实战指南
java·linux·服务器·top·linux调试
橘子海全栈攻城狮12 小时前
【最新源码】养老院系统管理A013
java·spring boot·后端·web安全·微信小程序
逻辑驱动的ken12 小时前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
冷雨夜中漫步13 小时前
Claude Code源码分析——Claude Code Agent Loop 详细设计文档
java·开发语言·人工智能·ai
直奔標竿13 小时前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring
one_love_zfl13 小时前
java面试-微服务组件篇
java·微服务·面试
一只大袋鼠13 小时前
Java进阶:CGLIB动态代理解析
java·开发语言
环流_14 小时前
HTTP 协议的基本格式
java·网络协议·http
爱滑雪的码农14 小时前
Java基础十三:Java中的继承、重写(Override)与重载(Overload)详解
java·开发语言