SpringBoot 第一章服务端表单数据校验
SpringBoot 第一章服务端表单数据校验
一:代码结构
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.alan</groupId> <artifactId>Validate1</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <thymeleaf.version>3.0.12.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.5.2</thymeleaf-layout-dialect.version> </properties> <dependencies> <!-- springBoot 的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- web 启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- SpringBoot 对表单数据校验的技术特点 1:Springboot 中使用了 hibernate-validate 校验框架 2: 在实体对象中添加 校验规则 @NotBlank//非空校验 3:controll 的对象传递参数方法中增加@valid 进行对校验对象开启校验 --> <!--spring boot 中使用hibernate validate--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
UsersController
package com.alan.validate.controller; /** @author Alan -liu @Email AlanLiu_2021@163.com @Web: https://www.cnblogs.com/ios9 @Create 2021-04-09 16:44 */ import javax.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import com.alan.validate.pojo.*; /** * Springboot 表单数据校验 * * UserController * @author Alan - liu * @date 2021/04/09 16:44 **/ @Controller public class UsersController { /** * * @author Alan - liu * @date 2021/04/09 17:56 * @param users 用来解决 add 页面的 users 对象不存在而报错 * 注意:由于springmvc 会将该对象放入到model 中传递,key的名称会使用该对象的驼峰式的命名规则、 * 来作为key。参数的变量需要与对象的名称相同。将首字母小写。 * @return java.lang.String */ @RequestMapping("/addUser") public String showPage(@ModelAttribute("user") Users users){ System.out.println("------------------------"); return "add"; } /** * 完成用户添加 * @valid 开启 对Users 对象的数据校验 * BindingResult :封装了校验结果 * @author Alan - liu * @date 2021/04/09 17:42 * @param users * @return java.lang.String */ @RequestMapping("/save") public String saveUsers(@ModelAttribute("user") @Valid Users users , BindingResult result){ //hasErrors() true 校验失败,有校验不合法数据 false 校验成功 校验的数据没有问题 if(result.hasErrors()){ return "add"; } System.out.println(users); return "ok"; } }
Users
package com.alan.validate.pojo; /** @author Alan -liu @Email AlanLiu_2021@163.com @Web: https://www.cnblogs.com/ios9 @Create 2021-04-09 16:51 */ import javax.validation.constraints.NotBlank; /** * * @author Alan - liu * @date 2021/04/09 16:51 **/ public class Users { @NotBlank(message="用户名不能为空") //非空校验 private String name ; @NotBlank(message="密码不能为空") //非空校验 private String password; private Integer age; public Users(String name, String password, Integer age) { this.name = name; this.password = password; this.age = age; } public Users(String name) { this.name = name; } public Users() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Users{" + "name='" + name + '\'' + ", password='" + password + '\'' + ", age=" + age + '}'; } }
App
package com.alan.validate; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
add.html
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html"> <head> <meta charset="UTF-8"> <title>添加用户</title> </head> <body> <form th:action="@{/save}" method="post"> 用户姓名:<input type="text" name="name"/><font color="red" th:errors="${user.name}"></font><br/> 用户密码:<input type="password" name="password" /><font color="red" th:errors="${user.password}"></font><br/> 用户年龄:<input type="text" name="age" /><font color="red" th:errors="${user.age}"></font><br/> <input type="submit" value="OK" /> </form> </body> </html>
ok.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>操作成功</title> </head> <body> 操作成功 !--------------------------OK------------ </body> </html>
运行效果
其他校验规则:
@NotBlank: 判断字符串是否为 null 或者是空串(去掉首尾空格)。 @NotEmpty: 判断字符串是否 null 或者是空串。 @Length: 判断字符的长度(最大或者最小) @Min: 判断数值最小值 @Max: 判断数值最大值 @Email: 判断邮箱是否合法
内置约束
2.3.内置约束 Hibernate Validator包含一组常用的基本约束。这些都是由JakartaBean验证规范定义的约束(请参见第2.3.1节,“JakartaBean验证约束”)。此外,Hibernate Validator提供了有用的自定义约束(请参阅第2.3.2节,“附加限制”). 2.3.1.JakartaBean验证约束 下面可以找到JakartaBean验证API中指定的所有约束的列表。所有这些约束都适用于字段/属性级别,在JakartaBean验证规范中没有定义任何类级约束。如果使用Hibernate对象-关系映射程序,则在为模型创建DDL时会考虑到一些约束(参见“Hibernate元数据影响”)。 Hibernate Validator允许将一些约束应用于比JakartaBean验证规范所要求的更多的数据类型(例如,@Max可以应用于字符串)。依赖此特性会影响您的应用程序在JakartaBean验证提供者之间的可移植性。 @AssertFalse 检查带注释的元素是否为false 支持的数据类型 Boolean, boolean Hibernate元数据影响 无 @AssertTrue 检查带注释的元素是否为真 支持的数据类型 Boolean, boolean Hibernate元数据影响 无 @DecimalMax(value=, inclusive=) 时,检查带注释的值是否小于指定的最大值。inclusive=假。否则,该值是否小于或等于指定的最大值。参数值是根据BigDecimal字符串表示 支持的数据类型 BigDecimal, BigInteger, CharSequence, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:Number和javax.money.MonetaryAmount(如果JSR 354 API实现在类路径上) Hibernate元数据影响 无 @DecimalMin(value=, inclusive=) 时,检查带注释的值是否大于指定的最小值。inclusive=假。否则,该值是否大于或等于指定的最小值。参数值是根据BigDecimal字符串表示 支持的数据类型 BigDecimal, BigInteger, CharSequence, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:Number和javax.money.MonetaryAmount Hibernate元数据影响 无 @Digits(integer=, fraction=) 检查带注释的值是否是一个最多可达integer数字和fraction小数位 支持的数据类型 BigDecimalBigInteger, CharSequence, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:Number和javax.money.MonetaryAmount Hibernate元数据影响 定义列精度和刻度 @Email 检查指定的字符序列是否为有效的电子邮件地址。可选参数regexp和flags允许指定电子邮件必须匹配的附加正则表达式(包括正则表达式标志)。 支持的数据类型 CharSequence Hibernate元数据影响 无 @Future 检查注释日期是否在将来。 支持的数据类型 java.util.Date, java.util.Calendar, java.time.Instant, java.time.LocalDate, java.time.LocalDateTime, java.time.LocalTime, java.time.MonthDay, java.time.OffsetDateTime, java.time.OffsetTime, java.time.Year, java.time.YearMonth, java.time.ZonedDateTime, java.time.chrono.HijrahDate, java.time.chrono.JapaneseDate, java.time.chrono.MinguoDate, java.time.chrono.ThaiBuddhistDate;附加由HV支持,如果Joda时间日期/时间API在类路径上:ReadablePartial和ReadableInstant Hibernate元数据影响 无 @FutureOrPresent 检查注释日期是在现在还是将来。 支持的数据类型 java.util.Date, java.util.Calendar, java.time.Instant, java.time.LocalDate, java.time.LocalDateTime, java.time.LocalTime, java.time.MonthDay, java.time.OffsetDateTime, java.time.OffsetTime, java.time.Year, java.time.YearMonth, java.time.ZonedDateTime, java.time.chrono.HijrahDate, java.time.chrono.JapaneseDate, java.time.chrono.MinguoDate, java.time.chrono.ThaiBuddhistDate;附加由HV支持,如果Joda时间日期/时间API在类路径上:ReadablePartial和ReadableInstant Hibernate元数据影响 无 @Max(value=) 检查带注释的值是否小于或等于指定的最大值。 支持的数据类型 BigDecimal, BigInteger, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:CharSequence(由字符序列表示的数值),任何子类型的Number和javax.money.MonetaryAmount Hibernate元数据影响 在列上添加检查约束。 @Min(value=) 检查带注释的值是否大于或等于指定的最小值。 支持的数据类型 BigDecimal, BigInteger, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:CharSequence(由字符序列表示的数值),任何子类型的Number和javax.money.MonetaryAmount Hibernate元数据影响 在列上添加检查约束。 @NotBlank 检查注释的字符序列不为NULL,并且修整的长度大于0。差异@NotEmpty该约束只能应用于字符序列,并且忽略了尾随空格。 支持的数据类型 CharSequence Hibernate元数据影响 无 @NotEmpty 检查带注释的元素是否为空或空。 支持的数据类型 CharSequence, Collection, Map和阵列 Hibernate元数据影响 无 @NotNull 检查注释的值是否为null 支持的数据类型 任何类型 Hibernate元数据影响 列不可空 @Negative 检查元素是否严格为负值。零值被认为无效。 支持的数据类型 BigDecimal, BigInteger, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:CharSequence(由字符序列表示的数值),任何子类型的Number和javax.money.MonetaryAmount Hibernate元数据影响 无 @NegativeOrZero 检查元素是负还是零。 支持的数据类型 BigDecimal, BigInteger, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:CharSequence(由字符序列表示的数值),任何子类型的Number和javax.money.MonetaryAmount Hibernate元数据影响 无 @Null 检查带注释的值是否为null 支持的数据类型 任何类型 Hibernate元数据影响 无 @Past 检查带注释的日期是否已过去。 支持的数据类型 java.util.Date,java.util.Calendar, java.time.Instant, java.time.LocalDate, java.time.LocalDateTime, java.time.LocalTime, java.time.MonthDay, java.time.OffsetDateTime, java.time.OffsetTime, java.time.Year, java.time.YearMonth, java.time.ZonedDateTime, java.time.chrono.HijrahDate, java.time.chrono.JapaneseDate, java.time.chrono.MinguoDate, java.time.chrono.ThaiBuddhistDate;附加由HV支持,如果Joda时间日期/时间API在类路径上:ReadablePartial和ReadableInstant Hibernate元数据影响 无 @PastOrPresent 检查注释日期是过去的还是现在的 支持的数据类型 java.util.Date,java.util.Calendar, java.time.Instant, java.time.LocalDate, java.time.LocalDateTime, java.time.LocalTime, java.time.MonthDay, java.time.OffsetDateTime, java.time.OffsetTime, java.time.Year, java.time.YearMonth, java.time.ZonedDateTime, java.time.chrono.HijrahDate, java.time.chrono.JapaneseDate, java.time.chrono.MinguoDate, java.time.chrono.ThaiBuddhistDate;附加由HV支持,如果Joda时间日期/时间API在类路径上:ReadablePartial和ReadableInstant Hibernate元数据影响 无 @Pattern(regex=, flags=) 检查带注释的字符串是否与正则表达式匹配。regex考虑给定的标志match 支持的数据类型 CharSequence Hibernate元数据影响 无 @Positive 检查元素是否严格为正。零值被认为无效。 支持的数据类型 BigDecimal, BigInteger, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:CharSequence(由字符序列表示的数值),任何子类型的Number和javax.money.MonetaryAmount Hibernate元数据影响 无 @PositiveOrZero 检查元素是正还是零。 支持的数据类型 BigDecimal, BigInteger, byte, short, int, long以及原语类型的相应包装器;另外还受HV支持:CharSequence(由字符序列表示的数值),任何子类型的Number和javax.money.MonetaryAmount Hibernate元数据影响 无 @Size(min=, max=) 检查带注释的元素的大小是否介于min和max(包括) 支持的数据类型 CharSequence, Collection, Map和阵列 Hibernate元数据影响 列长度将设置为max 在上面列出的参数之上,每个约束都有参数消息、组和有效载荷。这是JakartaBean验证规范的要求。 2.3.2.附加约束 除了JakartaBean验证API定义的约束之外,Hibernate Validator还提供了以下几个有用的自定义约束。除了一个例外,这些约束也适用于字段/属性级别,仅适用于@ScriptAssert是类级约束。 @CreditCardNumber(ignoreNonDigitCharacters=) 检查带注释的字符序列是否通过Luhn校验和测试。注意,这个验证的目的是检查用户的错误,而不是信用卡的有效性!另见信用卡号码剖析. ignoreNonDigitCharacters允许忽略非数字字符。默认情况是false. 支持的数据类型 CharSequence Hibernate元数据影响 无 @Currency(value=) 检查注释的货币单位。javax.money.MonetaryAmount是指定货币单位的一部分。 支持的数据类型 任何亚型javax.money.MonetaryAmount(如果JSR 354 API实现在类路径上) Hibernate元数据影响 无 @DurationMax(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=) 带注释的检查java.time.Duration元素不大于由注释参数构造的元素。在下列情况下允许平等inclusive标志设置为true. 支持的数据类型 java.time.Duration Hibernate元数据影响 无 @DurationMin(days=, hours=, minutes=, seconds=, millis=, nanos=, inclusive=) 带注释的检查java.time.Duration元素不少于由注释参数构造的元素。在下列情况下允许平等inclusive标志设置为true. 支持的数据类型 java.time.Duration Hibernate元数据影响 无 @EAN 检查带注释的字符序列是否有效。艾恩条形码。类型确定条形码的类型。默认情况是EAN-13。 支持的数据类型 CharSequence Hibernate元数据影响 无 @ISBN 检查带注释的字符序列是否有效。ISBN. type确定ISBN的类型。默认情况是ISBN-13。 支持的数据类型 CharSequence Hibernate元数据影响 无 @Length(min=, max=) 验证带注释的字符序列是否在min和max包括在内 支持的数据类型 CharSequence Hibernate元数据影响 列长度将设置为最大。 @CodePointLength(min=, max=, normalizationStrategy=) 验证带注释的字符序列的代码点长度在min和max包括在内。验证归一化值,如果normalizationStrategy已经设定好了。 支持的数据类型 CharSequence Hibernate元数据影响 无 @LuhnCheck(startIndex= , endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=) 检查注释字符序列中的数字是否通过Luhn校验和算法(另请参阅Luhn算法). startIndex和endIndex只允许在指定的子字符串上运行算法。checkDigitIndex允许将字符序列中的任意数字用作检查数字。如果未指定,则假定检查数字是指定范围的一部分。最后但并非最不重要,ignoreNonDigitCharacters允许忽略非数字字符。 支持的数据类型 CharSequence Hibernate元数据影响 无 @Mod10Check(multiplier=, weight=, startIndex=, endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=) 检查注释字符序列中的数字是否通过泛型mod 10校验和算法。multiplier确定奇数的乘数(默认值为3),weight偶数的权重(默认为1)。startIndex和endIndex只允许在指定的子字符串上运行算法。checkDigitIndex允许将字符序列中的任意数字用作检查数字。如果未指定,则假定检查数字是指定范围的一部分。最后但并非最不重要,ignoreNonDigitCharacters允许忽略非数字字符。 支持的数据类型 CharSequence Hibernate元数据影响 无 @Mod11Check(threshold=, startIndex=, endIndex=, checkDigitIndex=, ignoreNonDigitCharacters=, treatCheck10As=, treatCheck11As=) 检查注释字符序列中的数字是否通过mod 11校验和算法。threshold指定mod11乘法器增长的阈值;如果没有指定值,则乘法器将无限期地增长。treatCheck10As和treatCheck11As当mod 11校验和分别等于10或11时,指定要使用的校验位数。默认值分别为X和0。startIndex, endIndex checkDigitIndex和ignoreNonDigitCharacters的语义与@Mod10Check. 支持的数据类型 CharSequence Hibernate元数据影响 无 @Normalized(form=) 验证注释的字符序列是否根据给定的form. 支持的数据类型 CharSequence Hibernate元数据影响 无 @Range(min=, max=) 检查注释的值是否位于(包括)指定的最小值和最大值之间。 支持的数据类型 BigDecimal, BigInteger, CharSequence, byte, short, int, long以及原语类型的相应包装器。 Hibernate元数据影响 无 @ScriptAssert(lang=, script=, alias=, reportOn=) 检查是否可以根据带注释的元素成功地计算给定的脚本。为了使用这个约束,JSR 223定义的Java脚本API的实现(“Java脚本编写”)TM)必须是类路径的一部分。要计算的表达式可以用任何脚本或表达式语言编写,在类路径中可以找到与jsr 223兼容的引擎。reportOn属性报告特定属性(而不是整个对象)上的约束冲突。 支持的数据类型 任何类型 Hibernate元数据影响 无 @UniqueElements 检查带注释的集合是否仅包含唯一元素。相等值是使用equals()方法。默认消息不包括重复元素列表,但可以通过重写消息并使用{duplicates}消息参数重复元素的列表也包含在约束冲突的动态有效负载中。 支持的数据类型 Collection Hibernate元数据影响 无 @URL(protocol=, host=, port=, regexp=, flags=) 根据RFC 2396检查注释的字符序列是否是有效的URL。如果任何可选参数protocol, host或port则对应的URL片段必须与指定的值匹配。可选参数regexp和flags允许指定URL必须匹配的附加正则表达式(包括正则表达式标志)。默认情况下,此约束使用java.net.URL构造函数来验证给定字符串是否表示有效的URL。基于正则表达式的版本也是可用的-RegexpURLValidator-可以通过XML进行配置(请参见第8.2节,“通过constraint-mappings”)或编程API(请参见第12.15.2节,“以编程方式添加约束定义”). 支持的数据类型 CharSequence Hibernate元数据影响 无 2.3.2.1.具体国家的制约因素 Hibernate Validator还提供了一些特定于国家的限制,例如社会保障号码的验证。 如果您必须实现特定于国家的约束,请考虑将其作为Hibernate Validator的一个贡献! @CNPJ 检查附加注释的字符序列是否代表巴西企业纳税者登记号(地籍登记编号为“Pessoa Jurídica”) 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 巴西 @CPF 检查附加注释的字符序列是否代表巴西纳税人个人注册号码(地籍编号为“Pessoa Física”) 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 巴西 @TituloEleitoral 检查注释字符序列是否代表巴西选民身份证号码(蒂图洛·埃莱托拉尔) 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 巴西 @NIP 检查注释的字符序列是否代表波兰增值税标识号(尼普) 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 波兰 @PESEL 检查注释的字符序列是否代表波兰国民识别号(白塞) 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 波兰 @REGON 检查注释字符序列是否代表波兰纳税人的识别号(雷贡)。可应用于regon的9位和14位版本。 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 波兰 @INN 检查注释字符序列是否代表俄罗斯纳税人的识别号(客栈)。可适用于国际客栈的个人版本和法律版本。 支持的数据类型 CharSequence Hibernate元数据影响 无 国家 俄罗斯
为人:谦逊、激情、博学、审问、慎思、明辨、 笃行
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================
* 博客文章部分截图及内容来自于学习的书本及相应培训课程以及网络其他博客,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。 * @author Alan -liu * @Email no008@foxmail.com
转载请标注出处! ✧*꧁一品堂.技术学习笔记꧂*✧. ---> https://www.cnblogs.com/ios9/
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================
* 博客文章部分截图及内容来自于学习的书本及相应培训课程以及网络其他博客,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。 * @author Alan -liu * @Email no008@foxmail.com
转载请标注出处! ✧*꧁一品堂.技术学习笔记꧂*✧. ---> https://www.cnblogs.com/ios9/