wordpress汉化插件软件,网站优化服务,wordpress短代码开发,网站推广软件免费下载前言 在之前的悦享校园的开发中使用了SSM框架#xff0c;由于当时并没有使用参数参数校验工具#xff0c;方法的入参判断使用了大量的if else语句#xff0c;代码十分臃肿#xff0c;因此最近在重构代码时#xff0c;将框架改为SpringBoot后#xff0c;引入了Hibernate V…前言 在之前的悦享校园的开发中使用了SSM框架由于当时并没有使用参数参数校验工具方法的入参判断使用了大量的if else语句代码十分臃肿因此最近在重构代码时将框架改为SpringBoot后引入了Hibernate Validator校验工具对参数进行优雅校验(SSM同样可用)。本文将通过实例来演示如何使用该框架。
环境配置
JDK 1.8
Spring Boot 2.7.12
导入依赖 !--SpringBoot 2.3开始校验包单独组件需要手动引入 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency
基础校验 在正式开始之前需要先对以下的内容作以了解方便后续的学习。 校验注解
Hibernate Validator提供了丰富的校验注解来供我们使用这里列举一些比较常用的:
注解解释Null 验证对象是否为空 NotNull 验证对象是否为非空 NotBlank 用于String对象验证字符串不为空且trim()后长度大于0 Length 验证对象的长度是否符合 Size 验证对象长度是否在给定的范围之内(用于Array,Collection,Map,String) Min 入参对象的值不能小于该值(用于Number和String) Max 入参对象的值不能大于该值(用于Number和String) Digits 验证number和string的构成是否合法 Past 验证date和calendar对象是否在当前时间之前 Future 验证date和calendar对象是否在当前时间之后 Pattern 验证是否符合正则表达式规则 Email验证邮箱Positive 验证输入的对象是否非负数 Range 验证输入的对象的值是否在指定范围内
参数绑定
PathVariable 该注解用于接收具有Restful风格的参数如/api/v1/1001最终userId的值为1001。 如下代码中使用name属性可以指定GetMapping中的id名称与之对应从而可以自定义参数名称userId而不是使用默认名称id GetMapping(/v1/{id})
public void getMsg(PathVariable(name id) Integer userId){}
RequestParam 该注解用于接收查询参数如/api/v1/product?user123则user的值为123。该注解也可用于接收form-data类型的数据。 当在参数前使用RequireParam时当请求该方法时对应的参数必须存在否则会引发异常可使用RequireParam(required false)指明该参数非必须该注解在入参为null时可提供默认值。 GetMapping(/v1/product)
public void getMsg(RequestParam String user){}
RequestBody 该注解用于接收JSON格式的数据如请求为{name:123age:18}需要有对应的实体类作为映射。 PostMapping(/v1/user)
public void getMsg(RequestBody User user){}
Validated 该注解可以作用于类、方法、参数上用于开启参数校验。 Valid 该注解可以作用于方法、参数、字段、构造器上同样可以用于参数校验。 单参校验 将Validated注解用于类上可以不用在每个方法的参数上重复开启校验使用前面提的基础校验即可对参数作约束。 校验方法
RestController
RequestMapping(/v1/hello)
Slf4j
Validated
public class HelloController {/*** GetMapping 请求* param name 用户名称* param uid 用户uid* return*/GetMapping(/{id})public ResultDataVO getMsg(RequestParam String name,Max(value 10,message 最大值不能超过10)PathVariable(name id) int uid) {log.info(访问hello下的msg方法。);String result Hello,name id uid;return ResultDataVO.success(result);}
}
请求参数 响应结果 由于我们没有给String参数赋值因此默认为空字符串。但由于在uid上使用了Max注解因此当入参为100时便会出现异常而返回的JSON格式为全局的响应处理在后续的文章会提到。
对象校验 当我们在使用中往往会遇到多个参数的情况由于get请求对参数长度有限制且参数会拼接在URL中 因此对于此场景我们一般使用对象的方式来接收参数而对于我们的参数也将传入也将用JSON格式。 由于使用JSON格式传参将使用RequestBody注解除此之外还要使用Validated或Valid注解关于两者的选择只需要记住分组校验使用Validated否则二者均可。 即使在类上添加了Validated注解此处仍然需要以上两个注解之一否则参数校验将无效。 校验方法
RestController
RequestMapping(/v1/hello)
Slf4j
Validated
public class HelloController {/*** 对象校验示例* param user* return */PostMapping(/msg)public ResultDataVO(RequestBody Valid UserDTO user){return ResultDataVO.success(user.toString());}
}
UserDTO
Data
AllArgsConstructor
NoArgsConstructor
public class UserDTO {/*** id*/Min(value 1,message id值不合法)Positiveprivate Integer id;/*** 昵称*/NotBlank(message 用户名不能为空)Length(min 4,max10,message 用户名必须在4-10个字符之间)private String username;/*** 年龄*/Range(min 1,max120,message 年龄不在合法范围内)NotNull(message age不能为空)private Integer age;
} 上述代码中参数为UserDTO对象其中包含三个待校验的字段由于未涉及到分组校验因此校验方法中参数前使用Valid注解(Validated注解亦可)注意入参的字段名称需要和UserDTO中的名称一致。 请求参数 响应结果 分组校验 假设有这样的场景在用户登录和修改密码中两者分别需要如下参数登录时需要用户名、密码而修改时需要密码、新密码为了方便管理只使用了一个DTO类来存放上述的字段此时由于这些参数需要在不同的场景下校验而加上基础校验的注解会导致所有参数均被校验面对此问题我们将使用分组校验来解决。 可以看到如何代码中均是使用了Validate注解且注解中含有一个分组接口使用该接口可以帮助我们告知程序该对那些参数进行校验。 校验方法
RestController
Slf4j
RequestMapping(/local/auth)
Validated
public class LocalAuthController {Autowiredprivate LocalAuthService localAuthService;/*** 用户登录接口* param localAuthDTO 账号对象* return*/PostMapping(/login)LocalAuthVO loginCheck(RequestBody Validated(AuthCheckSequence.class) LocalAuthDTO localAuthDTO){return localAuthService.userLoginCheck(localAuthDTO);}/*** 用户修改密码接口* param localAuthDTO 账号对象* return*/PutMapping(/password)ResultDataVO userChangePassword(RequestBodyValidated(AuthChangeSequence.class)LocalAuthDTO localAuthDTO){return localAuthService.userModifyPassword(localAuthDTO);}
}
分组接口
AuthChangeSequence
/*** 分组校验用户登录*/public interface AuthCheckSequence {}
AuthCheckSequence
/*** 分组校验,密码修改*/
public interface AuthChangeSequence {}
LocalAuthDTO
Data
AllArgsConstructor
NoArgsConstructor
Builder
public class LocalAuthDTO {/*** 用户名*/NotBlank(message 用户名不能为空,groups AuthCheckSequence.class)Pattern(regexp ^[a-zA-Z0-9]{3,8}$, message 用户名必须由3-8个字母或数字组成,groups AuthCheckSequence.UsernameCheck.class)private String username;/*** 密码*/NotBlank(message 密码不能为空,groups AuthCheckSequence.class)Size(min 6,max 18, message 密码长度必须在6到18位之间,groups AuthCheckSequence.PasswordCheck.class)private String password;/*** 新密码修改密码时使用*/NotBlank(message 新密码不能为空,groups AuthChangeSequence.class)Size(min 6,max 18, message 新密码长度必须在6到18位之间,groups AuthChangeSequence.ChangePassword.class)private String newPassword;
}
请求参数 响应结果 从上图所示请求结果可以看出使用Validated注解分组校验接口后将只对该参数中标明了对应分组接口的字段进行校验并不会对全部参数进行校验。 顺序校验 由于用户人数增多我们将在对用户进行分组将在LocalAuthDTO中引入新的字段而我们所期望的是能够按照用户类型用户名密码的顺序来校验而不是像之前对象校验最终显示的结果那样随机进行校验并返回结果因此需要使用在分组校验的基础上做一些改进使其可以按照我们所指定的顺序执行校验以前面登录为例 校验方法
RestController
Slf4j
RequestMapping(/local/auth)
Validated
public class LocalAuthController {Autowiredprivate LocalAuthService localAuthService;/*** 用户登录接口* param localAuthDTO 账号对象* return*/PostMapping(/login)LocalAuthVO loginCheck(RequestBody Validated(AuthCheckSequence.class) LocalAuthDTO localAuthDTO){return localAuthService.userLoginCheck(localAuthDTO);}
} AuthCheckSequence 通过在该分组接口中新建接口并使用GroupSequence注解中参数的顺序来实现校验参数的顺序。如下将标识使用AuthCheckSequence分组的参数将按照用户类型、用户名、密码的顺序进行校验。 GroupSequence({AuthCheckSequence.UserTypeCheck.class, AuthCheckSequence.UsernameCheck.class, AuthCheckSequence.PasswordCheck.class})
public interface AuthCheckSequence {/*** 用户类型*/interface UserTypeCheck {};/*** 用户名校验*/interface UsernameCheck {};/*** 密码校验*/interface PasswordCheck {};
}
LocalAuthDTO
Data
AllArgsConstructor
NoArgsConstructor
Builder
public class LocalAuthDTO {/*** 用户类型 1.用户 2.商家 3.管理员,目前仅支持用户和商家类型注册*/NotNull(message 用户类型不能为空,groups AuthCheckSequence.UserTypeCheck.class)Range(min 1,max 3,message 用户类型不合法,groups AuthCheckSequence.UserTypeCheck.class)private Integer userType;/*** 用户名*/NotBlank(message 用户名不能为空,groups AuthCheckSequence.UsernameCheck.class)Pattern(regexp ^[a-zA-Z0-9]{3,8}$, message 用户名必须由3-8个字母或数字组成,groups AuthCheckSequence.UsernameCheck.class)private String username;/*** 密码*/NotBlank(message 密码不能为空,groups AuthCheckSequence.PasswordCheck.class)Size(min 6,max 18, message 密码长度必须在6到18位之间,groups AuthCheckSequence.PasswordCheck.class)private String password;
}
请求参数 响应结果