Hibernate-Validator(数据校验框架)
Posted 活学编程思想
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate-Validator(数据校验框架)相关的知识,希望对你有一定的参考价值。
目录
一、Hibernate-Validator 简介
hibernate-validator
是Hibernate
项目中的一个数据校验框架,它能够将数据校验从业务代码中脱离出来,增加代码可读性,同时也让数据校验变得更加方便、简单。
官网地址:http://hibernate.org/validator/documentation
二、项目中为什么要用校验框架
Java程序开发中,当你要处理一个程序的业务逻辑时,请求参数的数据校验是必须要处理的。当请求参数格式不正确的时候,需要程序监测到,并且返回对应的错误提示,以此来达到数据校验的目的。对于前后端分离开发过程中,数据校验还需要返回对应的状态码和错误提示信息。
三、添加依赖
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
如果使用了springboot
,则不需要引用任何依赖,因为spring-boot-starter-web
包中已经包含了Hibernate-Validator
依赖。
四、看一个入门级案例
-
现有一个实体类
@Data @AllArgsConstructor @NoArgsConstructor public class StudentPo @NotBlank(message = "用户名不能为空") private String name; @NotBlank(message = "邮箱不能为空") private String email;
-
POST接口控制器
POST请求必须要加@Valid// 注意:@Valid 不加这个注解,@NotBlank注解不生效 @RestController public class StudentPoController @RequestMapping(value = "/addStudent", method = RequestMethod.POST) public String addStudent(@Valid @RequestBody StudentPo student) System.out.println("student = [" + student + "]"); return "ok";
-
用postman测试
-
这种参数校验出现的异常,我们可以用全局异常处理类处理
@ControllerAdvice public class GlobalExceptionHandler @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public ResultEntity handleBindException(MethodArgumentNotValidException ex) FieldError fieldError = ex.getBindingResult().getFieldError(); return ResultEntity.faill(211, fieldError.getDefaultMessage(), null); @Data @AllArgsConstructor @NoArgsConstructor public class ResultEntity<T> private Integer code; private String message; private T data; public static <T> ResultEntity<T> faill(Integer code, String msg, T t) return new ResultEntity<T>(code, msg, t);
-
再次用postman测试
-
外加一个GET接口的控制器的写法
// Get请求需要在类上添加@Validated @RestController @Validated public class StudentController @RequestMapping(value = "/addStudent1",method = RequestMethod.GET) public String addStudent1(@NotBlank(message = "name不能为空") String name) System.out.println("name = [" + name + "]"); return "ok addStudent1";
五、常用注解
注解 | 说明 | 用法 | 例子 |
---|---|---|---|
@Nul | 被注释的元素必须为 null | ||
@NotNull | 被注释的元素必须不为 null | @NotNull 用在基本类型上 | |
@AssertTrue | 被注释的元素必须为 true | ||
@AssertFalse | 被注释的元素必须为 false | ||
@Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 | ||
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 | ||
@DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 | ||
@DecimalMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 | ||
@Size(max, min) | 被注释的元素的大小必须在指定的范围内,元素必须为集合,代表集合个数 | ||
@Pattern(regexp = ) | 正则表达式校验 | ||
@Digits (integer, fraction) | 被注释的元素必须是一个数字,其值必须在可接受的范围内 | ||
@Past | 被注释的元素必须是一个过去的日期 | ||
@Future | 被注释的元素必须是一个将来的日期 | ||
被注释的元素必须是电子邮箱地址 | |||
@Length(min=, max=) | 被注释的字符串的大小必须在指定的范围内,必须为数组或者字符串,若微数组则表示为数组长度,字符串则表示为字符串长度 | ||
@NotEmpty | 被注释的字符串的必须非空 | @NotEmpty 用在集合类上面 | |
@Range(min=, max=) | 被注释的元素必须在合适的范围内 | ||
@NotBlank | 被注释的字符串的必须非空 | @NotBlank 用在String上面 | |
@URI | 字符串是否是一个有效的URL |
注意:
1.@NotNull:不能为null,但可以为empty(“”," “,” “)
2.@NotEmpty:不能为null,而且长度必须大于0 (” “,” ")
3.@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0(“test”) 即:必须有实际字符
六、使用groups的校验
-
1、情景说明
同一个对象要复用,比如UserDTO
在更新时候要校验userId
,在保存的时候不需要校验userId
,在两种情况下都要校验username
,那就用上groups
了: -
第一步:先定义groups的分组接口Create和Update
import javax.validation.groups.Default; public interface Create extends Default import javax.validation.groups.Default; public interface Update extends Default
-
第二步:再在需要校验的地方@Validated声明校验组
/** * 走参数校验注解的 groups 组合校验 * * @param userDTO * @return */ @PostMapping("/update/groups") public RspDTO update(@RequestBody @Validated(Update.class) UserDTO userDTO) userService.updateById(userDTO); return RspDTO.success();
-
第三步:在DTO中的字段上定义好groups = 的分组类型
@Data public class UserDTO implements Serializable private static final long serialVersionUID = 1L; /*** 用户ID*/ @NotNull(message = "用户id不能为空", groups = Update.class) private Long userId; /** * 用户名 */ @NotBlank(message = "用户名不能为空") @Length(max = 20, message = "用户名不能超过20个字符", groups = Create.class, Update.class) @Pattern(regexp = "^[\\\\u4E00-\\\\u9FA5A-Za-z0-9\\\\*]*$", message = "用户昵称限制:最多20字符,包含文字、字母和数字") private String username; /** * 手机号 */ @NotBlank(message = "手机号不能为空") @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]9$", message = "手机号格式有误", groups = Create.class, Update.class) private String mobile; /** * 性别 */ private String sex; /** * 邮箱 */ @NotBlank(message = "联系邮箱不能为空") @Email(message = "邮箱格式不对") private String email; /** * 密码 */ private String password; /*** 创建时间 */ @Future(message = "时间必须是将来时间", groups = Create.class) private Date createTime;
hibernate-validator校验框架学习
1、引入jar包
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>2.2.4</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.4</version> </dependency>
注意:
- 当使用hibernate-validator更高版本时,会报一个java.lang.ClassNotFoundException: javax.el.ELManager错误,目前博主还未找到兼容的方案,因此采用了5.4.1.Final版本。
- 当不添加javax.el-api和javax.el依赖时,项目也可以运行,因为tomcat容器包含hibernate-validator所依赖的类
2、spring-mvc配置
<mvc:annotation-driven conversion-service="conversionService" validator="validator"/> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property> <property name="validationMessageSource" ref="messageSource"></property> </bean> <!-- 检验错误信息资源配置文件 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:validator/validationMessages</value> </list> </property> <!-- 资源文件编码格式 --> <property name="fileEncodings" value="utf-8"/> <!-- 对资源文件内容的缓存时间,单位秒 --> <property name="cacheSeconds" value="120"/> </bean>
3、在实体上增加相应注解校验信息
private Integer stuId; @NotBlank(message = "{notnull}") @Size(max = 20, min = 2, message = "姓名长度在2-20之间") private String name; @Max(value = 200, message = "最大年龄200岁") @Min(value = 6, message = "最小年龄6岁") private Integer age;
注意:
message=“{notnull}”会去配置的错误文件中查找,即validator/validationMessages.properties文件中查找notnull的配置对应的错误信息。
4、使用方式
a) 自动校验
在实体上增加@Validated注解,表示要校验这个实体。BindingResult用于接收验证后的错误信息。
@RequestMapping(value = "/add", method = { RequestMethod.GET, RequestMethod.POST }) public String addStudent(Model model, HttpServletRequest request, @Validated Student stu, BindingResult bindingResult) { if (HttpRequestContext.GET.equalsIgnoreCase(request.getMethod())) { return "prictice/student/addStudent"; } else { if (bindingResult.hasErrors()) { List<ObjectError> errors = bindingResult.getAllErrors(); model.addAttribute("errors", errors); return "prictice/student/addStudent"; } stu.setRegTime(new Date()); stu.setStatus(true); studentService.addStudent(stu); return "redirect:/student/list"; } }
b) 主动校验
通过工具类,主动验证某个实体类
新建工具类ValidateUtil.java
public class ValidateUtil { public static <T> void validate(T obj) { LocalValidatorFactoryBean validator = (LocalValidatorFactoryBean) SpringContextHolder.getBean("validator"); Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj); Iterator<ConstraintViolation<T>> iter = constraintViolations.iterator(); while (iter.hasNext()) { ConstraintViolation<T> error = iter.next(); StringBuffer buffer = new StringBuffer().append("[") .append(error.getPropertyPath().toString()).append("]") .append(error.getMessage()); throw new IllegalArgumentException(buffer.toString()); } } }
或者可以使用下面的代码获取validator
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
调用
@RequestMapping(value = "/add") public String addStudent(@RequestParam Student stu) { ValidateUtil.validate(stu); return "redirect:/student/list" }
5、常用注解
注解 |
作用 |
AssertTrue |
布尔值为真 |
AssertFalse |
布尔值为假 |
Null |
引用为空 |
NotNull |
引用不为空 |
NotEmpty |
字符串引用和值都不是空 |
Min |
数字的最小值 |
Max |
数字的最大值 |
Past |
日期必须是过去 |
Future |
日期必须是未来 |
Pattern |
字符串必须匹配正则表达式 |
Valid |
递归验证引用 |
Size |
验证字符串是否在Size范围内 |
|
验证字符串是否是一个有效的电子邮箱 |
URL |
字符串是否是一个有效的URL |
注意:
- @NotEmpty 用在集合类上面
- @NotBlank 用在String上面
- @NotNull 用在基本类型上
- @Email和@URL是Hibernate Validator自定义的,假如使用其他的Bean Validation实现,可能没有这两个注解。
- 和JPA注解一样,如果验证注解添加到字段上,Hibernate就会直接读取字段的值。如果注解到Getter方法上,Hibernate就会调用方法取得值。在一个类中不要同时应用这两种方式,会导致重复验证的问题。
- 如果在一个集合上应用Valid注解, Hibernate就会递归验证集合中的每一个元素。
以上是关于Hibernate-Validator(数据校验框架)的主要内容,如果未能解决你的问题,请参考以下文章
JSR303校验 —— hibernate-validator实现
Java后端校验-使用hibernate-validator校验JavaBean
Hibernate-Validator框架完成服务端参数据校验(巨详细)
SpringBoot整合Hibernate-Validator校验器