SpringMVC 学习(十一)之数据校验

目录

1 数据校验介绍

2 普通校验

3 分组校验

4 参考文档


1 数据校验介绍

在实际的项目中,一般会有两种校验数据的方式:客户端校验和服务端校验

  • 客户端校验:这种校验一般是在前端页面使用 JS 代码进行校验,主要是验证输入数据的合法性,不合法的数据则没有必要再发送至服务端了。前端校验可以有效的提高用户体验,但是无法确保数据完整性,因为前端用户可以方便的拿到请求地址,然后直接发送请求,传递非法参数
  • 服务端校验:可以有效的保证数据安全与完整性,但是用户体验要差一点,所以客户端校验和服务端校验通常两者结合使用

        SpringMVC 提供了两种方法来对用户的输入数据进行校验:一种是 SpringMVC 自带的 Validation 校验框架,它提供了简洁的注解和验证规则,易于使用,并且与 SpringMVC 框架集成良好;另一种是利用 JRS-303 验证框架进行验证,JRS-303 验证框架的优势在于它的灵活性和可扩展性,可以与其他框架或技术进行集成。

注解作用
@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)必须符合指定的正则表达式
@Email必须是格式正确的Email地址
@Length被注释的字符串大小必须在指定的范围内
@NotEmpty被注释的字符串不能是空字符串
@Range被注释的元素必须在指定的范围内

@NotEmpty、@NotNull 和 @NotBlank 三种的区别:

  • @NotNull:一般用在基本数据类型上(包括包装类),对象不能为 null,但可以为 empty,即为空集(size = 0)。
  • @NotEmpty:可以作用在 String、List、Map 和 Array 等,对象不能为 null,而且长度必须大于0 (size > 0)
  • @NotBlank:只能作用在 String 上,不能为 null,而且调用 trim() 后,长度必须大于 0 ,即必须有实际字符

2 普通校验

导入依赖

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.0.Final</version>
</dependency>

在 SpringMVC 配置文件中配置校验器并注入到处理器适配器中

<!-- 配置MVC注解驱动,配置注入校验器 -->
<mvc:annotation-driven validator="validator"/>

<!-- 配置校验器 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <!-- 校验器-->
    <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
    <!-- 指定校验使用的资源文件,如果不指定则默认使用classpath下的ValidationMessages.properties -->
    <property name="validationMessageSource" ref="messageSource"/>
</bean>
<!-- 校验错误信息配置文件 -->
<bean id="messageSource"
      class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <!-- 资源文件名-->
    <property name="basenames">
        <list>
            <value>classpath:CustomValidationMessages</value>
        </list>
    </property>
    <!-- 资源文件编码格式 -->
    <property name="defaultEncoding" value="utf-8"/>
    <!-- 对资源文件内容缓存时间,单位秒 -->
    <property name="cacheSeconds" value="120"/>
</bean>

创建 CustomValidationMessages.properties 配置文件,和上述代码中的校验错误信息配置文件名对应也可以将错误提示信息放在一个类中

#添加校验错误提示信息
user.id.isEmpty="用户的ID不能为空!"
user.userName.isEmpty="用户名不能为空!"
user.userName.length="用户名为1~6个字符!"
user.userPwd.isEmpty="密码不能为空!"
user.userPwd.length="密码的长度为5~15个字符!"
user.userEmail.isEmpty="邮箱不能为空!"
user.userEmail.format="输入的邮箱格式不正确!"

需要校验的类 User

public class User {

    @NotNull(message = "{user.id.isEmpty}")
    private Integer id;

    @NotEmpty(message = "{user.userName.isEmpty}")
    @Length(min = 1, max = 6, message = "{user.userName.length}")
    private String userName;

    @NotEmpty(message = "{user.userPwd.isEmpty}")
    @Length(min = 5, max = 15, message = "{user.userPwd.length}")
    private String userPwd;

    @NotEmpty(message = "{user.userEmail.isEmpty}")
    @Email(message = "{user.userEmail.format}")
    private String userEmail;

    // 省略了 Getter、Setter 方法

校验控制器

@Validated 注解和 BindingResult 是成对出现的,中间不能穿插其它的形参,否则会报 400错误,其他形参只能加在它们后面

@Controller
public class ValidateController {

    @ResponseBody
    @RequestMapping("/validate")
    // 形参前面加上 @Validated 注解表示这个实体类需要进行数据校验
    // BindingResult 封装数据绑定的校验结果
    public void validate(@Validated User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            //校验未通过,获取所有的异常信息并展示出来
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError allError : allErrors) {
                System.out.println(allError.getObjectName() + ":" + allError.getDefaultMessage());
            }
        }
    }
}

index.jsp

<input name="userName"/> 与 private String userName; 对应

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>添加用户</title>
    </head>
    <body>
        <form action="${pageContext.request.contextPath}/validate" method="post">
            ID号:<input type="text" name="id" placeholder="请输入ID号"/> <br>
            姓名:<input type="text" name="userName" placeholder="请输入姓名"/> <br>
            密码:<input type="password" name="userPwd" placeholder="请输入密码"/> <br>
            邮箱:<input type="text" name="userEmail" placeholder="请输入邮箱"/> <br>
            <input type="submit" value="提交" />
        </form>
    </body>
</html>

执行结果

 

3 分组校验

        某个属性设置了多种数据校验,可以将这些校验分组,然后 Controller 方法选择校验分组对数据进行校验

首先定义校验组,所谓的校验组,它其实就是空接口:

// 分组校验接口1
public interface ValidationGroup1 {
}

// 分组校验接口2
public interface ValidationGroup2 {
}

对校验进行分组

public class User {

    // groups属性表示校验属于哪个组,可以定义多个
    @NotNull(message = "{user.id.isEmpty}", groups = {ValidationGroup2.class})
    private Integer id;

    @NotEmpty(message = "{user.userName.isEmpty}", groups = {ValidationGroup1.class, ValidationGroup2.class})
    @Length(min = 1, max = 6, message = "{user.userName.length}", groups = {ValidationGroup1.class, ValidationGroup2.class})
    private String userName;

    @NotEmpty(message = "{user.userPwd.isEmpty}", groups = {ValidationGroup1.class})
    @Length(min = 5, max = 15, message = "{user.userPwd.length}", groups = {ValidationGroup1.class})
    private String userPwd;

    @NotEmpty(message = "{user.userEmail.isEmpty}", groups = {ValidationGroup2.class})
    @Email(message = "{user.userEmail.format}", groups = {ValidationGroup2.class})
    private String userEmail;

    // getter setter 构造器 toString 省略...
}

执行结果

4 参考文档

SpringMVC入门学习(十五)----数据校验 - 唐浩荣 - 博客园 (cnblogs.com)

springMVC如何对输入数据校验实现代码_java_脚本之家 (jb51.net)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/425359.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Zookeeper3:客户端命令

文章目录 客户端命令连接服务端Zookeeper客户端内置命令 ls - 节点信息 客户端命令 连接服务端Zookeeper //客户端连接服务端zookeeper 默认连的本机2181端口的zookeeper cd /opt/module/zookeeper-3.9.1/bin && sh zkCli.sh//客户端连接远程服务端zookeeper cd /op…

详细了解C++中的namespace命名空间

键盘敲烂&#xff0c;月薪过万&#xff0c;同学们&#xff0c;加油呀&#xff01; 目录 键盘敲烂&#xff0c;月薪过万&#xff0c;同学们&#xff0c;加油呀&#xff01; 一、命名空间的理解 二、&#xff1a;&#xff1a;作用域运算符 三、命名空间&#xff08;namespace&…

Vulnhub靶机:Bellatrix

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.4&#xff09; 靶机&#xff1a;Bellatrix&#xff08;10.0.2.9&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/hogwa…

【C++】const成员

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. const成员3. 取地址及const取地址操作符重载 1. 前言 在之前已经已经分享过了关于 【C】类和对象之常引用与运算符重载&#xff0c;这次分享的有关const的内容&#xff0c;话不多说&#xff0c;正文开始。…

spring-security 项目实战(一)个人健康档案

spring-security 项目实战&#xff08;一&#xff09;个人健康档案 项目说明项目地址框架信息 代码分析配置类解析默认登录页登录接口执行逻辑登录认证成功之后重定向到main页面过程未登录之前访问 /main生成默认登录页点击登录 登录之后访问 /main执行流程清空认证信息 项目来…

Leetcoder Day27| 贪心算法part01

语言&#xff1a;Java/Go 理论 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 什么时候用贪心&#xff1f;可以用局部最优退出全局最优&#xff0c;并且想不到反例到情况 贪心的一般解题步骤 将问题分解为若干个子问题找出适合的贪心策略求解每一个子…

数据类型和变量

1.数据类型 在Java中数据类型主要分为两类&#xff1a;基本数据类型和引用数据类型。 基本数据类型有四类八种&#xff1a; 1. 四类&#xff1a;整型、浮点型、字符型以及布尔型 2.八种&#xff1a; 整形是分为如上四种 byte short int long 浮点型分为 float 和double …

【Java EE】线程安全的集合类

目录 &#x1f334;多线程环境使用 ArrayList&#x1f38d;多线程环境使⽤队列&#x1f340;多线程环境使⽤哈希表&#x1f338; Hashtable&#x1f338;ConcurrentHashMap ⭕相关面试题&#x1f525;其他常⻅问题 原来的集合类, 大部分都不是线程安全的. Vector, Stack, HashT…

Java---文件,流✨❤️

文章目录 1.遍历文件夹2.遍历子文件夹3.练习流4.以字节流的形式读取文件内容5.以字节流的形式向文件写入数据顶折纠问6 .写入数据到文件 1.遍历文件夹 一般说来操作系统都会安装在C盘&#xff0c;所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出…

全栈入门,前后端入门--springboot3+vue3制作一个后台管理项目

一&#xff1a;前言 1&#xff1a;因为本人也是全栈初学者&#xff0c;现在主职是公司前端&#xff0c;鉴于当前行业形式&#xff0c;单单只掌握一门语言已经不再吃香&#xff0c;甚至有点危险&#xff0c;35岁危机极大可能提前。作为00后要始终保持危机意识&#xff0c;不至于…

[C++]使用纯opencv去部署yolov9的onnx模型

【介绍】 部署 YOLOv9 ONNX 模型在 OpenCV 的 C 环境中涉及一系列步骤。以下是一个简化的部署方案概述&#xff0c;以及相关的文案。 部署方案概述&#xff1a; 模型准备&#xff1a;首先&#xff0c;你需要确保你有 YOLOv9 的 ONNX 模型文件。这个文件包含了模型的结构和权…

opencv生成一张图片

opencv也可以创造出一张照片&#xff0c;下面就是创造一张照片&#xff0c;并存放到项目文件夹下的示例 #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <vector> using namespace cv…

sql注入之sqli-labs-less-2 数值型报错注入

输入?id1 进行试探,第二关数值型&#xff0c;没有字符串的单引号&#xff0c;所以输入单引号报错&#xff0c; 经试探?id1 order by 5 -- 如果是错误的数值&#xff0c;显示如下&#xff1a; 正确 的为&#xff1a; ?id1 order by 3 -- 进行注入查看回显点&#xff1a; …

个体工商户营业执照怎么在网上年检?

第一步PC端登录国家企业信用信息公示系统&#xff01; 第二步点企业信息填报&#xff01; 第三步选择省份&#xff01; 第四步登陆方式&#xff01; 第五步点左上角年度报告填写&#xff01; 第六步下滑浏览点确认&#xff01; 第七步按照实际情况填写&#xff01; 第八步…

Linux笔记--文件权限

一、相关概念 Linux最优秀的地方之一就在于多人多任务环境。为了让各个使用者有较为保密的文件数据&#xff0c;文件的权限管理尤为重要。 ●文件的可存取身份: owner:文件拥有者 group:文件所属用户组 others:其他人 ●文件权限: r: read&#xff0c;读 文件:是否能查看文件内…

代码随想录刷题笔记 DAY 41 | 整数拆分 No.343 | 不同的二叉搜索树 No.96

文章目录 Day 4101. 整数拆分&#xff08;No. 343&#xff09;<1> 题目<2> 笔记<3> 代码 02. 不同的二叉搜索树&#xff08;No. 96&#xff09;<1> 题目<2> 笔记<3> 代码 Day 41 01. 整数拆分&#xff08;No. 343&#xff09; 题目链接 …

2024.3.1 小项目

1、机械臂 #include <myhead.h> #define SER_IP "192.168.125.32" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.68.148" //客户端IP #define CLI_PORT 9999 /…

Mybatis plus扩展功能-Db静态工具

目录 1 前言 2 使用方法 2.1 Db静态工具拥有的部分方法 2.2 举例 1 前言 在我们的服务层中&#xff0c;有时为了实现一个方法需要引入其它的Mapper层方法&#xff0c;但是&#xff0c;这样可能出现循环依赖。虽然Spring已经给我们解决了简单的循环依赖问题&#xff0c;但是…

【书生·浦语大模型实战营】第4节 课后作业

XTuner 大模型单卡低成本微调实战 0. 课程链接1. 课后作业1.2 进阶作业 0. 课程链接 课程链接&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/README.md 1. 课后作业 构建数据集&#xff0c;使用 XTuner 微调 InternLM-Chat-7B 模型, 让模型学习到它是你…

数字化转型导师坚鹏:证券公司数字化思维升级之道

证券公司数字化思维升级之道 ——数字化思维之六脉神剑 课程背景&#xff1a; 很多证券公司存在以下问题&#xff1a; 不知道数字化转型如何改变思维模式&#xff1f; 不清楚需要建立什么样的数字化思维&#xff1f; 不知道如何开展数字化思维提升工作&#xff1f; 课…