正则校验0到300以内的小数_SpringBoot入门建站全系列(三十三)集成validator校验接口数据...

eaaf58f879d92f965e73fab10737674f.png

SpringBoot入门建站全系列(三十三)集成validator校验接口数据

一、概述

在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,如果我们直接将这些校验写死在代码里,将会遇到这种现象: 1. 验证代码繁琐,重复劳动 2. 方法内代码显得冗长 3. 代码可读性不高

所以,我们可以使用hibernate validator来对字段的校验工作统一完成。

spring-boot-starter-web中默认引入了hibernate-validator,因此,在SpringBoot项目中,我们可以直接使用hibernate-validator的特性。

这一篇篇文章本应该放在SpringBoot入门建站全系列的前面章节讲述,这里权做对该系列的补充了。

首发地址:

品茗IT: https://www.pomit.cn/p/2437125163256321

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

二、基础知识

首先,基础知识是必须要了解的,我这里整理了下最新的注解,比网上一下子搜到的博客更全面。

validator的功能是由hibernate-validator提供的,所以在Spring官方文档里是找不到关于它的说明的,需要到hibernate-validator官网查看: https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-builtin-constraints

| 注解 | 释义 | 场景 | | ------ | ------ | ------ | | @AssertFalse | 验证注解的元素值是false | Boolean, boolean | | @AssertTrue | 验证注解的元素值是true | Boolean, boolean | | @DecimalMax(value=x) | 验证注解的元素值小于等于@ DecimalMax指定的value值 | BigDecimal,BigInteger,CharSequence,byte,short,int,long和原始类型的相应的包装类; | | @DecimalMin(value=x) | 验证注解的元素值小于等于@ DecimalMin指定的value值 | BigDecimal,BigInteger,CharSequence,byte,short,int,long和原始类型的相应的包装类; | | @Digits(integer=整数位数, fraction=小数位数) | 验证注解的元素值的整数位数和小数位数上限 | BigDecimal的,BigInteger,CharSequence,byte,short,int,long和原始类型的相应的包装类; | | @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; | | @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; | | @Max(value=x) | 验证注解的元素值小于等于@Max指定的value值 | BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类; | | @Min(value=x) | 验证注解的元素值大于等于@Min指定的value值 | BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类; | | @NotNull | 验证注解的元素值不是null | 任意 | | @Null | 验证注解的元素值是null | 任意 | | @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; | | @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; | | @Pattern(regex=正则表达式, flag=) | 验证注解的元素值与指定的正则表达式匹配 | CharSequence | | @Size(min=最小值, max=最大值) | 验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小 | CharSequence,Collection,Map和数组 | | @Valid | 验证关联的对象,如账户对象里有一个订单对象,指定验证订单对象 | Any non-primitive type(引用类型) | | @NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) | CharSequence,Collection,Map和数组 | | @Range(min=最小值, max=最大值) | 验证注解的元素值在最小值和最大值之间 | CharSequence, Collection, Map and Arrays,BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive types | | @NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 | CharSequence | | @Length(min=下限, max=上限) | 验证注解的元素值长度在min和max区间内 | CharSequence | | @Email | 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 | CharSequence | | @Negative | 检查元素是否严格为负。零值被视为无效。 | BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类 | | @NegativeOrZero | 检查元素是负数还是零。 | BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类 | | @Positive | 检查元素是否严格为正。零值被视为无效。 | BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类 | | @NegativeOrZero | 检查元素是正数还是零。 | BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类 | | @URL(protocol=, host=, port=, regexp=, flags=) | 检查字符序列是否为有效URL。 | CharSequence | | @CreditCardNumber | 检查带注释的字符序列是否通过了Luhn校验和测试。 | CharSequence | | @Currency | 检查带注释的货币单位javax.money.MonetaryAmount是否为指定货币单位的一部分。 | CharSequence | | @DurationMax | 检查带注释的java.time.Duration元素不大于由注释参数构造的元素。 | java.time.Duration | | @DurationMin | 检查带注释的java.time.Duration元素不少于由注释参数构造的元素。 | java.time.Duration | | @EAN | 检查带注释的字符序列是有效的EAN条形码。 | CharSequence | | @ISBN | 检查带注释的字符序列是有效的ISBN。 | CharSequence | | @CodePointLength | 验证带注释的字符序列的代码点长度在之间min并max包括在内。 | CharSequence | | @LuhnCheck | 检查带注释的字符序列中的数字是否通过Luhn校验和算法 | CharSequence | | @Mod10Check | 检查带注释的字符序列中的数字是否通过通用mod 10校验和算法。 | CharSequence | | @Mod11Check | 检查带注释的字符序列中的数字是否通过了mod 11校验和算法。 | CharSequence | | @SafeHtml | 检查带注释的值是否包含潜在的恶意片段,例如。 | CharSequence | | @ScriptAssert | 检查是否可以根据带注释的元素成功评估给定脚本。 | 任意 | | @UniqueElements | 检查带注释的集合仅包含唯一元素。 | Collection |</p> <h3>三、实体校验</h3> <p>假设当前有个实体叫userInfo</p> <h4>3.1 实体</h4> <pre><code class="java">package com.cff.springbootwork.validator.vo; import java.util.Date; import java.util.List; import javax.validation.constraints.AssertFalse; import javax.validation.constraints.AssertTrue; import javax.validation.constraints.Digits; import javax.validation.constraints.Email; import javax.validation.constraints.Future; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.Negative; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; import javax.validation.constraints.Past; import javax.validation.constraints.Pattern; import javax.validation.constraints.Positive; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; import org.hibernate.validator.constraints.URL; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class UserInfo { @Null(message = &quot;创建时间不能填&quot;) @JsonFormat(pattern = &quot;yyyy-MM-dd&quot;, locale = &quot;zh&quot;, timezone = &quot;GMT+8&quot;) private Date createTime; @NotEmpty(message = &quot;用户名不能为空&quot;) private String userName; @NotBlank(message = &quot;姓名不能为空或空字符串&quot;) private String name; @Negative(message = &quot;冬天温度在0°以下&quot;) private Integer temperatureWinter; @Positive(message = &quot;夏天温度在0°以上&quot;) private Integer temperatureSummer; @Digits(integer = 11, message = &quot;手机号是11位整数哦&quot;, fraction = 0) private String mobile; @NotNull(message = &quot;年龄不能为空&quot;) @Min(value = 10, message = &quot;年龄太小了&quot;) @Max(value = 35, message = &quot;年龄太大了&quot;) private Integer age; @Size(min = 0, max = 2, message = &quot;你女朋友个数在0-2之间&quot;) private List&lt;String&gt; girlFrinds; @Range(min = 0, max = 100, message = &quot;你钱包里的钱在0-2之间&quot;) private Integer money; @Length(min = 4, max = 64, message = &quot;地址在4-64之间&quot;) private String address; @AssertTrue(message = &quot;对象必须是人&quot;) private Boolean people; @AssertFalse(message = &quot;不能上来就删除&quot;) private Boolean delete; @Pattern(regexp=&quot;[0-9]{6}&quot;,message = &quot;密码格式错误&quot;) private String password; @Email(message = &quot;email格式错误&quot;) private String email; @JsonFormat(pattern = &quot;yyyy-MM-dd&quot;, locale = &quot;zh&quot;, timezone = &quot;GMT+8&quot;) @Future(message = &quot;失效时间比当前时间晚&quot;) private Date expireTime; @JsonFormat(pattern = &quot;yyyy-MM-dd&quot;, locale = &quot;zh&quot;, timezone = &quot;GMT+8&quot;) @Past(message = &quot;出生日期比当前时间早&quot;) private Date birthDate; @URL(message = &quot;url填写错误&quot;) private String url; } </code></pre> <h4>3.2 Web层数据接收</h4> <p>只需要加上@Valid注解即可,然后通过BindingResult来接收校验错误。</p> <pre><code class="java"> @RequestMapping(value = &quot;/test&quot;) public List&lt;String&gt; set(@Valid @RequestBody UserInfo userInfo, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List&lt;String&gt; errorMsg = bindingResult.getAllErrors().stream().map(s -&gt; s.getDefaultMessage()) .collect(Collectors.toList()); return errorMsg; } return Collections.singletonList(&quot;0000&quot;); } </code></pre> <p>这里,是打印了所有错误结果,如果只校验是否错误,抛出第一个错误,这样写即可:</p> <pre><code class="java">@RequestMapping(value = &quot;/test&quot;) public List&lt;String&gt; set(@Valid @RequestBody UserInfo userInfo, BindingResult bindingResult) { if (bindingResult.hasErrors()) { String errorMsg = bindingResult.getAllErrors().get(0).getDefaultMessage(); return Collections.singletonList(errorMsg); } return Collections.singletonList(&quot;0000&quot;); } </code></pre> <h4>3.3 校验不通过测试</h4> <pre><code>请求参数: { &quot;createTime&quot;:&quot;2018-08-09&quot;, &quot;userName&quot;: &quot;&quot;, &quot;name&quot;: &quot; &quot;, &quot;age&quot;: 9, &quot;mobile&quot;: &quot;123123123&quot;, &quot;girlFrinds&quot;: [&quot;1号&quot;,&quot;2号&quot;,&quot;3号&quot;], &quot;money&quot;: 101, &quot;temperatureWinter&quot;: 0, &quot;temperatureSummer&quot;: -1, &quot;address&quot;: &quot;12&quot;, &quot;people&quot;: false, &quot;delete&quot;: true, &quot;password&quot;: &quot;123&quot;, &quot;email&quot;: &quot;11@&quot;, &quot;expireTime&quot;:&quot;2019-11-11&quot;, &quot;birthDate&quot;:&quot;2020-11-11&quot;, &quot;url&quot;:&quot;qwe&quot; } 返回结果: [ &quot;你女朋友个数在0-2之间&quot;, &quot;地址在4-64之间&quot;, &quot;密码格式错误&quot;, &quot;email格式错误&quot;, &quot;创建时间不能填&quot;, &quot;你钱包里的钱在0-2之间&quot;, &quot;对象必须是人&quot;, &quot;出生日期比当前时间早&quot;, &quot;冬天温度在0°以下&quot;, &quot;年龄太小了&quot;, &quot;失效时间比当前时间晚&quot;, &quot;url填写错误&quot;, &quot;夏天温度在0°以上&quot;, &quot;不能上来就删除&quot;, &quot;姓名不能为空或空字符串&quot;, &quot;用户名不能为空&quot; ] </code></pre> <h4>3.4 校验通过测试</h4> <pre><code>请求参数: { &quot;createTime&quot;:&quot;&quot;, &quot;userName&quot;: &quot; &quot;, &quot;name&quot;: &quot;cff&quot;, &quot;age&quot;: 11, &quot;mobile&quot;: &quot;13333333333&quot;, &quot;girlFrinds&quot;: [&quot;1号&quot;,&quot;2号&quot;], &quot;money&quot;: 100, &quot;temperatureWinter&quot;: -1, &quot;temperatureSummer&quot;: 12, &quot;address&quot;: &quot;12345&quot;, &quot;people&quot;: true, &quot;delete&quot;: false, &quot;password&quot;: &quot;123456&quot;, &quot;email&quot;: &quot;11@qq.com&quot;, &quot;expireTime&quot;:&quot;2020-11-11&quot;, &quot;birthDate&quot;:&quot;2019-11-11&quot;, &quot;url&quot;:&quot;http://www.pomit.cn&quot; } 返回结果: [ &quot;0000&quot; ] </code></pre> <h3>四、级联校验</h3> <p>如果一个对象持有另一个对象的引用,可以使用@Valid注解进行级联校验。 如下所示:</p> <h4>4.1 实体</h4> <pre><code class="java">package com.cff.springbootwork.validator.vo; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class UserRole { @NotEmpty(message = &quot;用户名不能为空&quot;) private String userName; @NotNull(message = &quot;roleId不能为空&quot;) private Integer roleId; @Valid private UserInfo userInfo; } </code></pre> <h4>4.2 测试Web</h4> <pre><code class="java">@RequestMapping(value = &quot;/test1&quot;) public List&lt;String&gt; test1(@Valid @RequestBody UserRole userRole, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List&lt;String&gt; errorMsg = bindingResult.getAllErrors().stream().map(s -&gt; s.getDefaultMessage()) .collect(Collectors.toList()); return errorMsg; } return Collections.singletonList(&quot;0000&quot;); } </code></pre> <h4>4.3 测试结果</h4> <pre><code>请求数据: { &quot;userName&quot;: &quot;&quot;, &quot;roleId&quot;: 1, &quot;userInfo&quot;:{ &quot;createTime&quot;:&quot;2018-08-09&quot;, &quot;userName&quot;: &quot;&quot;, &quot;name&quot;: &quot; &quot;, &quot;age&quot;: 9, &quot;mobile&quot;: &quot;123123123&quot;, &quot;girlFrinds&quot;: [&quot;1号&quot;,&quot;2号&quot;,&quot;3号&quot;], &quot;money&quot;: 101, &quot;temperatureWinter&quot;: 0, &quot;temperatureSummer&quot;: -1, &quot;address&quot;: &quot;12&quot;, &quot;people&quot;: false, &quot;delete&quot;: true, &quot;password&quot;: &quot;123&quot;, &quot;email&quot;: &quot;11@&quot;, &quot;expireTime&quot;:&quot;2019-11-11&quot;, &quot;birthDate&quot;:&quot;2020-11-11&quot;, &quot;url&quot;:&quot;qwe&quot; } } 返回结果: [ &quot;失效时间比当前时间晚&quot;, &quot;用户名不能为空&quot;, &quot;用户名不能为空&quot;, &quot;你女朋友个数在0-2之间&quot;, &quot;密码格式错误&quot;, &quot;你钱包里的钱在0-2之间&quot;, &quot;姓名不能为空或空字符串&quot;, &quot;url填写错误&quot;, &quot;冬天温度在0°以下&quot;, &quot;对象必须是人&quot;, &quot;email格式错误&quot;, &quot;不能上来就删除&quot;, &quot;年龄太小了&quot;, &quot;夏天温度在0°以上&quot;, &quot;地址在4-64之间&quot;, &quot;创建时间不能填&quot;, &quot;出生日期比当前时间早&quot; ] </code></pre> <h3>五、手动校验</h3> <p>有时候,不用使用@Valid 自动校验,需要手动调起validator进行校验,可以使用<code>validator.validate(roleInfo);</code>进行校验:</p> <h4>5.1 实体</h4> <pre><code class="java">package com.cff.springbootwork.validator.vo; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class RoleInfo { @NotNull(message = &quot;roleId不能为空&quot;) private Integer roleId; @NotEmpty(message = &quot;roleName不能为空&quot;) private String roleName; } </code></pre> <h4>5.2 测试</h4> <p>Validator(import javax.validation.Validator;) 在SpringBoot中,可以作为bean之间被注入。</p> <pre><code class="java">@Autowired Validator validator; @RequestMapping(value = &quot;/test2&quot;) public List&lt;String&gt; test2(@RequestParam(&quot;roleId&quot;) Integer roleId, @RequestParam(&quot;roleName&quot;) String roleName) { RoleInfo roleInfo = new RoleInfo(roleId, roleName); Set&lt;ConstraintViolation&lt;RoleInfo&gt;&gt; sets = validator.validate(roleInfo); if(sets.isEmpty())return Collections.singletonList(&quot;0000&quot;); List&lt;String&gt; errorMsg = sets.stream().map(s -&gt; s.getMessage()).collect(Collectors.toList()); return errorMsg; } </code></pre> <h3>六、分组校验</h3> <p>分组校验就是处理特殊情况下的校验,使不同的调用走不同的校验组。</p> <p>如,一个对象A持有另一个对象B的引用,对象B中某些字段不想在对象A校验的时候被校验到,可以使用分组校验。</p> <h4>6.1 实体</h4> <p>假设有两个实体:</p> <pre><code class="java">import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class UserRoleInfo { @NotEmpty(message = &quot;用户名不能为空&quot;) private String userName; @NotNull(message = &quot;roleId不能为空&quot;) private Integer roleId; @Valid private RoleInfo roleInfo; } </code></pre> <pre><code class="java">import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class RoleInfo { @NotNull(message = &quot;roleId不能为空&quot;, groups=RoleGroup.class) private Integer roleId; @NotEmpty(message = &quot;roleName不能为空&quot;, groups=RoleGroup.class) private String roleName; } </code></pre> <p>注意,这里的groups必须是接口。接口内容任意,只是个标识而已。</p> <pre><code class="java">public interface RoleGroup { } </code></pre> <p><strong><code>Default.class(javax.validation.groups.Default)</code>是默认分组,不需要自己建立.</strong></p> <h4>6.2 测试不带分组</h4> <pre><code class="java">import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.validation.ConstraintViolation; import javax.validation.Validator; import javax.validation.groups.Default; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.cff.springbootwork.validator.vo.RoleGroup; import com.cff.springbootwork.validator.vo.RoleInfo; import com.cff.springbootwork.validator.vo.UserRoleInfo; @RestController @RequestMapping(&quot;/valid&quot;) public class ValidatorRest { @Autowired Validator validator; @RequestMapping(value = &quot;/test3&quot;) public List&lt;String&gt; test3(@RequestParam(&quot;roleId&quot;) Integer roleId, @RequestParam(&quot;userName&quot;) String userName, @RequestParam(&quot;roleName&quot;) String roleName) { UserRoleInfo userRoleInfo = new UserRoleInfo(); userRoleInfo.setRoleId(roleId); userRoleInfo.setUserName(userName); RoleInfo roleInfo = new RoleInfo(roleId, roleName); userRoleInfo.setRoleInfo(roleInfo); Set&lt;ConstraintViolation&lt;UserRoleInfo&gt;&gt; sets = validator.validate(userRoleInfo); if (sets.isEmpty()) return Collections.singletonList(&quot;0000&quot;); List&lt;String&gt; errorMsg = sets.stream().map(s -&gt; s.getMessage()).collect(Collectors.toList()); return errorMsg; } } </code></pre> <p>结果:</p> <pre><code>请求参数: roleId:1 userName: roleName: 返回结果: [ &quot;用户名不能为空&quot; ] </code></pre> <h4>6.2 测试带分组</h4> <p>注意,<code>Default.class</code>是默认分组。</p> <pre><code class="java">import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.validation.ConstraintViolation; import javax.validation.Validator; import javax.validation.groups.Default; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.cff.springbootwork.validator.vo.RoleGroup; import com.cff.springbootwork.validator.vo.RoleInfo; import com.cff.springbootwork.validator.vo.UserRoleInfo; @RestController @RequestMapping(&quot;/valid&quot;) public class ValidatorRest { @Autowired Validator validator; @RequestMapping(value = &quot;/test3&quot;) public List&lt;String&gt; test3(@RequestParam(&quot;roleId&quot;) Integer roleId, @RequestParam(&quot;userName&quot;) String userName, @RequestParam(&quot;roleName&quot;) String roleName) { UserRoleInfo userRoleInfo = new UserRoleInfo(); userRoleInfo.setRoleId(roleId); userRoleInfo.setUserName(userName); RoleInfo roleInfo = new RoleInfo(roleId, roleName); userRoleInfo.setRoleInfo(roleInfo); Set&lt;ConstraintViolation&lt;UserRoleInfo&gt;&gt; sets = validator.validate(userRoleInfo, RoleGroup.class, Default.class); if (sets.isEmpty()) return Collections.singletonList(&quot;0000&quot;); List&lt;String&gt; errorMsg = sets.stream().map(s -&gt; s.getMessage()).collect(Collectors.toList()); return errorMsg; } } </code></pre> <p>结果:</p> <pre><code>请求参数: roleId:1 userName: roleName: 返回结果: [ &quot;roleName不能为空&quot;, &quot;用户名不能为空&quot; ] </code></pre> <h3>七、自定义注解校验</h3> <p>有时候,我们仍需要自定义校验注解,如,我这里定义一个只校验0或1数据的验证器。</p> <h4>7.1 自定义注解</h4> <pre><code class="java">package com.cff.springbootwork.validator.custom; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; /** * 自定义类校验注解 * 作用于类,用以校验0/1类型数据 * @author cff * */ @Target(value = {ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=TypeZeroOneValidator.class) public @interface ZeroOne { String message() default &quot;参数有误&quot;; Class&lt;?&gt;[] groups() default {}; Class&lt;? extends Payload&gt;[] payload() default {}; } </code></pre> <h4>7.2 自定义Validator</h4> <pre><code class="java">package com.cff.springbootwork.validator.custom; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class TypeZeroOneValidator implements ConstraintValidator&lt;ZeroOne, Object&gt; { @Override public void initialize(ZeroOne constraintAnnotation) { } @Override public boolean isValid(Object obj, ConstraintValidatorContext context) { if (obj == null) return true; int curNum = 0; if (obj instanceof String) { String s = (String) obj; curNum = Integer.parseInt(s); } else if (obj instanceof Boolean) { boolean b = ((Boolean) obj).booleanValue(); if (b) { curNum = 1; } } else if (obj instanceof Long) { curNum = ((Long) obj).intValue(); } else { curNum = ((Integer) obj).intValue(); } if (curNum == 0 || curNum == 1) return true; return false; } } </code></pre> <h4>7.3 测试实体</h4> <pre><code class="java">package com.cff.springbootwork.validator.vo; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import com.cff.springbootwork.validator.custom.ZeroOne; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class RoleInfoZeroOne { @NotNull(message = &quot;roleId不能为空&quot;) private Integer roleId; @NotEmpty(message = &quot;roleName不能为空&quot;) private String roleName; @ZeroOne(message = &quot;deleted只能为0/1&quot;) private Integer deleted; } </code></pre> <h4>7.4 测试Web</h4> <p>跟普通使用方法一样,无需更改。</p> <pre><code class="java">@RequestMapping(value = &quot;/test4&quot;) public List&lt;String&gt; test4(@Valid @RequestBody RoleInfoZeroOne roleInfoZeroOne, BindingResult bindingResult) { if (bindingResult.hasErrors()) { List&lt;String&gt; errorMsg = bindingResult.getAllErrors().stream().map(s -&gt; s.getDefaultMessage()) .collect(Collectors.toList()); return errorMsg; } return Collections.singletonList(&quot;0000&quot;); } </code></pre> <h4>7.5 测试结果</h4> <pre><code>请求参数: { &quot;roleId&quot;:1, &quot;deleted&quot;:3, &quot;roleName&quot;: &quot;cff&quot; } 返回结果: [ &quot;deleted只能为0/1&quot; ] </code></pre> <p><a href="https://www.pomit.cn/lecture.html">品茗IT-博客专题:https://www.pomit.cn/lecture.html</a>汇总了<a href="https://www.pomit.cn/lecture/springunion.html">Spring专题</a>、<a href="https://www.pomit.cn/lecture/springbootfull.html">Springboot专题</a>、<a href="https://www.pomit.cn/lecture/springcloudfull.html">SpringCloud专题</a>、<a href="https://www.pomit.cn/lecture/webbasics.html">web基础配置</a>专题。</p> <h3>快速构建项目</h3> <p>Spring项目快速开发工具:</p> <p><a href="https://www.pomit.cn/java/spring/spring.html">一键快速构建Spring项目工具</a></p> <p><a href="https://www.pomit.cn/java/spring/springboot.html">一键快速构建SpringBoot项目工具</a></p> <p><a href="https://www.pomit.cn/java/spring/springcloud.html">一键快速构建SpringCloud项目工具</a></p> <p><a href="https://www.pomit.cn/java/java/sqlToSpringboot.html">一站式Springboot项目生成</a></p> <p><a href="https://www.pomit.cn/java/java/sqlToMybatis.html">Mysql一键生成Mybatis注解Mapper</a></p> <p><a href="https://www.pomit.cn/java/spring/spring.html">Spring组件化构建</a></p> <p><a href="https://www.pomit.cn/java/spring/springboot.html">SpringBoot组件化构建</a></p> <p><a href="https://www.pomit.cn/java/spring/springcloud.html">SpringCloud服务化构建</a></p> <p>喜欢这篇文章么,喜欢就加入我们一起讨论Java Web吧! <img alt="品茗IT交流群" src="https://img-blog.csdnimg.cn/20190430181302249.png" /></p>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值