一、项目搭建
1、使用springboot搭建一个web工程
建web工程,不使用骨架创建maven的Java工程即可,不需要创建maven的web工程。
2、添加父工程坐标和添加web启动器
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
查看spring-boot-starter-web依赖,发现web模块默认使用了hibernate-validator:
3、创建启动类
@SpringBootApplication public class MySpringBootApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class); } }
二、对象校验
1、创建实体类Agent
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data public class Agent { /** * 代理人姓名 */ @NotNull(message = "姓名不能为空") private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; }
注意:一定要加@Data注解,否则无法获取请求体中的值,即使请求体中参数不为空,也会校验失败。
注意:如果使用@NotNull,如果是空字符串就不会报错。而用NotBlank,空字符串也会报错。
通过注释名即可推断出校验的内容,message用作校验失败时的提示信息。
2、编写controller
@RestController public class TestController { @PostMapping( "/test") public String add(@RequestBody @Validated Agent agent) { return "你好"; } }
3、使用postman发起请求
结果如下:
{ "timestamp": "2022-09-07T03:48:12.999+0000", "status": 400, "error": "Bad Request", "errors": [ { "codes": [ "NotBlank.agent.email", "NotBlank.email", "NotBlank.java.lang.String", "NotBlank" ], "arguments": [ { "codes": [ "agent.email", "email" ], "arguments": null, "defaultMessage": "email", "code": "email" } ], "defaultMessage": "邮箱不能为空", "objectName": "agent", "field": "email", "rejectedValue": "", "bindingFailure": false, "code": "NotBlank" } ], "message": "Validation failed for object='agent'. Error count: 1", "path": "/test" }
三、统一异常处理
1、异常捕获类
经过对校验异常的debug发现,该异常为MethodArgumentNotValidException
import com.zwh.entity.RsData;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
@ControllerAdvice
@RestController
public class ExceptionHandler {
private String paramValid = "参数不合法:";
/**
* 用来处理validation异常,捕获post请求Body实体属性参数校验异常信息
*
* @param ex
* @return
*/
@org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class)
public RsData resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
if (!CollectionUtils.isEmpty(objectErrors)) {
StringJoiner msgJoiner = new StringJoiner(",");
Set<String> errors = new HashSet<>(objectErrors.size() / 2);
for (ObjectError objectError : objectErrors) {
errors.add(objectError.getDefaultMessage());
}
for (String error : errors) {
msgJoiner.add(error);
}
String errorMessage = msgJoiner.toString();
return RsData.fail(paramValid + errorMessage);
}
return RsData.fail(paramValid + ex.getMessage());
}
}
2、返回的响应体类
@Data public class RsData { private static final String SUCCESS = "0"; private static final String FAIL = "1"; private String code; private Object result; private String message; public static RsData success(String msg) { RsData rs = new RsData(); rs.setCode(SUCCESS); rs.setMessage(msg); return rs; } public static RsData success(String msg, Object result) { RsData rs = new RsData(); rs.setCode(SUCCESS); rs.setMessage(msg); rs.setResult(result); return rs; } public static RsData error(String msg) { RsData rs = new RsData(); rs.setCode(FAIL); rs.setMessage(msg); return rs; } public static RsData error(String msg, Object result) { RsData rs = new RsData(); rs.setCode(FAIL); rs.setMessage(msg); rs.setResult(result); return rs; } public static RsData fail(String result) { RsData rs = new RsData(); rs.setCode(FAIL); rs.setMessage("失败"); rs.setResult(result); return rs; } }
3、修改Controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
4、postman访问
四、对象集合校验
User实体类
@Data public class User { @NotBlank(message = "姓名不能为空") private String name; @NotBlank(message = "性别不能为空") private String sex; }
ListValidation类
/*** * 由于Validator只能验证对象合法性,故数组方式需自定义处理,这是方式一 * 也可直接在controller类上加@Validated注解 * @param <E> */ public class ListValidation<E> implements List<E> { @Delegate @Valid public List<E> list = new ArrayList<>(); @Override public String toString() { return list.toString(); } }
controller
@RestController public class Demo1Controller { @PostMapping( "/test1") public String add(@RequestBody @Validated ListValidation<User> userList) { return "你好"; } }
修改异常捕获类,添加如下内容
// 将Spring DataBinder配置为使用直接字段访问 @InitBinder private void activateDirectFieldAccess(DataBinder dataBinder) { dataBinder.initDirectFieldAccess(); }
异常捕获类完整代码
@ControllerAdvice @RestController public class ExceptionHandler { private String paramValid = "参数不合法:"; // 将Spring DataBinder配置为使用直接字段访问 @InitBinder private void activateDirectFieldAccess(DataBinder dataBinder) { dataBinder.initDirectFieldAccess(); } /** * 用来处理validation异常,捕获post请求Body实体属性参数校验异常信息 * * @param ex * @return */ @org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class) public RsData resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) { List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors(); if (!CollectionUtils.isEmpty(objectErrors)) { StringJoiner msgJoiner = new StringJoiner(","); Set<String> errors = new HashSet<>(objectErrors.size() / 2); for (ObjectError objectError : objectErrors) { errors.add(objectError.getDefaultMessage()); } for (String error : errors) { msgJoiner.add(error); } String errorMessage = msgJoiner.toString(); return RsData.fail(paramValid + errorMessage); } return RsData.fail(paramValid + ex.getMessage()); } }
启动项目,postman请求
@Valid可以用在方法、构造函数、方法参数和成员属性(字段)上,支持嵌套检测。@Validated可以用在类型、方法和方法参数上,但是不能用在成员属性(字段)上,不支持嵌套检测。
五、分组校验
当我们遇到不同场景需要有不同的校验规则时候,我们可以使用分组校验。如:一个请求只校验姓名,一个请求只校验email
1、创建分组接口
名称自定义,也不需要实现,只是能做区分分组就行
FirstGroup.class
public interface FirstGroup { }
SecondGroup.class
public interface SecondGroup { }
2、实体类中使用分组
import javax.validation.constraints.NotBlank; @Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空",groups = SecondGroup.class) private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空",groups = FirstGroup.class) private String email; }
注意:如果将email划入FirstGroup,将name划到SecondGroup,而@Validated注解不指定分组(默认为Default),
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
此时由于Default分组没有要校验的属性,相当于不校验,结果如下:
{ "code": "0", "result": null, "message": "success" }
3、修改controller
(1)、当指定FirstGroup时:
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated(FirstGroup.class) Agent agent) { return RsData.success("success"); } }
结果如下:
{ "code": "1", "result": "参数不合法:邮箱不能为空", "message": "失败" }
(2)、当指定SecondGroup时
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated(SecondGroup.class) Agent agent) { return RsData.success("success"); } }
结果如下:
{ "code": "1", "result": "参数不合法:姓名不能为空", "message": "失败" }
(3)、当不指定分组时
当然不写时会有一个默认分组,所有不指定分组的属性都划到这个分组
实体类:
@Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空") private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; }
controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
测试
{ "code": "1", "result": "参数不合法:邮箱不能为空,姓名不能为空", "message": "失败" }
修改实体类:
import javax.validation.constraints.NotBlank; import javax.validation.groups.Default; @Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空",groups = Default.class) private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空",groups = Default.class) private String email; }
修改controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated(Default.class) Agent agent) { return RsData.success("success"); } }
结果:
{ "code": "1", "result": "参数不合法:邮箱不能为空,姓名不能为空", "message": "失败" }
六、级联校验
使用Valid注解实现级联校验
新建Address实体类
@Data public class Address { @NotBlank(message = "省不能为空") private String province; @NotBlank(message = "市不能为空") private String city; @NotBlank(message = "区不能为空") private String region; }
修改Agent实体类
import lombok.Data; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.List; @Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空") private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; @Valid @NotNull(message = "地址不能为空") private List<Address> addressList; }
controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
测试
七、JSR提供的校验注解API
注意:@NotEmpty 校验集合;@NotBlank 校验String类型;@NotNull 校验基本类型。
@Null 被注释的元素必须为 null @NotNull 被注释的元素必须不为 null @AssertTrue 被注释的元素必须为 true @AssertFalse 被注释的元素必须为 false @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @Size(max=, min=) 被注释的元素的大小必须在指定的范围内 @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内 @Past 被注释的元素必须是一个过去的日期 @Future 被注释的元素必须是一个将来的日期 @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator提供的校验注解
@NotBlank(message =) 验证字符串非null,且长度必须大于0 @Email 被注释的元素必须是电子邮箱地址 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内 @NotEmpty 被注释的字符串的必须非空 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内
正则校验
1 匹配首尾空格的正则表达式:(^\s*)|(\s*$) 2 整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$ 3 只能输入数字:"^[0-9]*$"。 4 只能输入n位的数字:"^\d{n}$"。 5 只能输入至少n位的数字:"^\d{n,}$"。 6 只能输入m~n位的数字:。"^\d{m,n}$" 7 只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"。 8 只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"。 9 只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"。 10 只能输入非零的正整数:"^\+?[1-9][0-9]*$"。 11 只能输入非零的负整数:"^\-[1-9][]0-9"*$。 12 只能输入长度为3的字符:"^.{3}$"。 13 只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"。 14 只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"。 15 只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"。 16 只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"。 17 只能输入由数字、26个英文字母或者下划线组成的字符串:"^\w+$"。 18 验证用户密码:"^[a-zA-Z]\w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。 19 验证是否含有^%&',;=?$\"等字符:"[^%&',;=?$\x22]+"。 20 只能输入汉字:"^[\u4e00-\u9fa5]{0,}$" 21 验证Email地址:"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"。 22 验证InternetURL:"^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"。 23 验证电话号码:"^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$"正确格式为:"XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。 24 验证身份证号(15位或18位数字):"^\d{15}|\d{18}$"。 25 验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"1"~"12"。 26 验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"和"1"~"31"。 27 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 28 匹配双字节字符(包括汉字在内):[^\x00-\xff] 29 应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1) 30 String.prototype.len=function(){return this.replace(/[^\x00-\xff]/g,"aa").length;} 31 匹配空行的正则表达式:\n[\s| ]*\r 32 匹配html标签的正则表达式:<(.*)>(.*)<\/(.*)>|<(.*)\/> 33 仅允许输入1或2:^[12]$ 34 大于0的正整数:^[1-9][0-9]*$ 35 大于1的正整数:^(([1-9]\d+)|([2-9]))$
校验日期格式:
(1)、日期格式:yyyy-MM-dd
@NotNull(message = "生产日期不为空") @Pattern(regexp = "^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)$",message = "日期格式不正确!") private String produceDate;
(2)、日期格式:yyyy-MM-dd HH:mm:ss
public class demo { public static void main(String[] args) { String timeRegex = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; boolean flag = Pattern.matches(timeRegex, "2012-12-31 12:07:59"); System.out.println(flag); } }
结果为true
(3)、日期格式:yyyy/MM/dd
public class demo { public static void main(String[] args) { String timeRegex2 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\/(((0[13578]|1[02])\\/(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)\\/(0[1-9]|[12][0-9]|30))|(02\\/(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\/02\\/29)$"; System.out.println(Pattern.matches(timeRegex2,"2018/12/31")); } }
结果为true
(4)、日期格式:yyyy/MM/dd HH:mm:ss
public class demo { public static void main(String[] args) { String timeRegex3 = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\/(((0[13578]|1[02])\\/(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)\\/(0[1-9]|[12][0-9]|30))|(02\\/(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))\\/02\\/29))\\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; System.out.println(Pattern.matches(timeRegex3,"2018/12/30 12:29:59")); } }
结果为true
日期格式校验参考文档:https://blog.csdn.net/xingxiupaioxue/article/details/105998503
八、自定义校验器
案例一
1、自定义校验注解
import com.zwh.config.ListRangeValidatorForString; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 当前值必须在给定的列表中 */ @Target({FIELD}) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {ListRangeValidatorForString.class}) public @interface ListRange { String message() default ""; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; String[] value() default {}; }
2、校验器
import com.zwh.anno.ListRange; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.Objects; public class ListRangeValidatorForString implements ConstraintValidator<ListRange, String> { private String[] range; @Override public void initialize(ListRange listRange) { this.range = listRange.value(); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (Objects.isNull(value)) { return true; } return Arrays.asList(range).contains(value); } }
3、使用注解:
@Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空") private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; @Valid @NotNull(message = "地址不能为空") private List<Address> addressList; @NotBlank(message = "性别不能为空") @ListRange(value = {"male", "female"}, message = "性别必须在[male,female]之间") private String gender; }
4、测试
案例二:日期格式校验
1、自定义校验注解
@IsDate注解
/** * 日期类型校验 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = {IsDateValidator.class}) // 指定自定义的校验器 public @interface IsDate { // 提示信息 String message() default "日期格式不正确"; String dateType() default "yyyy-MM-dd hh:mm:ss"; // 不加这俩参数 error msg: contains Constraint annotation, but does not contain a groups parameter. // 必须包含这两个参数 Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
@IsDatetime注解
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = {IsDateTimeValidator.class}) // 指定自定义的校验器 public @interface IsDatetime { // 提示信息 String message() default "日期格式不正确"; String dateType() default "yyyy-MM-dd HH:mm:ss"; // 不加这俩参数 error msg: contains Constraint annotation, but does not contain a groups parameter. // 必须包含这两个参数 Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2、校验器
IsDateValidator
import com.ljxx.common.util.DateUtil; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; /** * 日期类型校验器 */ public class IsDateValidator implements ConstraintValidator<IsDate, String> { private String dateType; @Override public void initialize(IsDate obj) { dateType = obj.dateType(); } /** * 通过该方法,对参数进行验证,看是否通过。 * @param value 修饰字段的值。 * @param context 上下文 * @return true:验证通过。 false:验证不通过。 */ @Override public boolean isValid(String value, ConstraintValidatorContext context) { return DateUtil.isvalidDate(value,dateType); } }
IsDatetimeValidator
import com.ljxx.common.util.DateUtil; import org.apache.commons.lang3.StringUtils; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class IsDateTimeValidator implements ConstraintValidator<IsDatetime, String> { private String dateType; @Override public void initialize(IsDatetime obj) { dateType = obj.dateType(); } /** * 通过该方法,对参数进行验证,看是否通过。 * * @param value 修饰字段的值。 * @param context 上下文 * @return true:验证通过。 false:验证不通过。 */ @Override public boolean isValid(String value, ConstraintValidatorContext context) { if(StringUtils.isNotEmpty(value)){ return DateUtil.isvalidDate(value,dateType); } return true; } }
3、使用注解:
@IsDatetime(message = "开始时间格式不正确")
@NotBlank(message = "开始时间不能为空")
private String beginTime;
//过期时间
@IsDate(message = "过期时间格式不正确", dateType = "yyyy-MM-dd")
private String expireDate;
案例三:校验值是否在数据字典中
1、自定义校验注解
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 当前值必须在给定的列表中 */ @Target({FIELD}) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {DictTypeRangeValidatorForString.class}) public @interface DictTypeRange { String message() default ""; String[] value() default {}; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2、校验器
import com.ljxx.client.DictServiceClient; import com.ljxx.model.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.*; public class DictTypeRangeValidatorForString implements ConstraintValidator<DictTypeRange, String> { // private String[] range; private String[] dictCodes; @Autowired private DictServiceClient dictServiceClient; @Override public void initialize(DictTypeRange dictTypeRange) { this.dictCodes = dictTypeRange.value(); } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { if (Objects.isNull(value)) { return true; } // 先查询数据字典获取所有的出库类型 List<String> dictCodeList = Arrays.asList(this.dictCodes); if (CollectionUtils.isEmpty(dictCodeList)) { return false; } Result result1 = dictServiceClient.queryDictByDictTypeCode(dictCodeList.get(0)); List<Map> list1 = (List<Map>) result1.getData(); List<String> dictTypeList = new ArrayList<>(); //局部变量:随着方法的调用而存在,随着方法的调用完毕而消失。 list1.forEach(map -> { String dictCode = (String) map.get("dictCode"); dictTypeList.add(dictCode); }); return dictTypeList.contains(value); } }
3、使用注解:
@NotBlank(message = "出库单据类型编码不能为空") @DictTypeRange(value = {"OUTSTORE_TYPE"},message = "出库类型错误") private String orderType;
案例四:validator校验List集合的合法性
import lombok.experimental.Delegate; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; /*** * 由于Validator只能验证对象合法性,故数组方式需自定义处理,这是方式一 * 也可直接在controller类上加@Validated注解 * @param <E> */ public class ValidationList<E> implements List<E> { @Delegate @Valid public List<E> list = new ArrayList<>(); @Override public String toString() { return list.toString(); } }
Controller
@PostMapping("/xxxxxx") @ResponseBody public Result2 push(@RequestBody @Validated ValidationList<CtsProPushVO> ctsProPushVOS, HttpServletRequest request) { return regService.push(ctsProPushVOS,request); }
注意:ctsProPushVOS为List<CtsProPushVO>。
CtsProPushVOS
@Data public class CtsProPushVO { @NotBlank(message = "编码不能为空") private String code; @NotBlank(message = "是否监管不能为空") @ListRange(value = {"1", "0"}, message = "是否监管的值必须为0或1") private String monitor; }