在前后端传递数据的时候,往往后端需要校验传递数据的格式,比如用户名的格式,密码是否为空。我们可以在service层编写代码判断,但是当我们在多处需要校验传递来的数据的时候,就会出现大量重复的代码,一旦出错,就需要多处修改,非常麻烦,而且这样我们的软件将会非常槽糕。这时,我们可以用Hibernate Validation的注解来进行校验,十分的方便简洁,Hibernate Validation是Spring自带的校验框架,在javax.validation包下可以找到。下面我们来详细讲解一下Hibernate Validation的使用以及如何自定义注解来处理数据的校验。

一、使用Hibernate Validation校验注解

如何使用Hibernate Validation呢?我们来假设这样一个场景,我们需要创建一个用户,这时后端需要校验前台传来的数据。下面我们来看看这个实例怎么编写代码。

首先,用MockMvc来伪造请求进行测试,这里为了方便不编写前端代码了。

@Testpublic void whenPostSuccess() throws Exception {Date date=(Date) new java.util.Date();System.out.println(date.getTime());String content="{\"username\":\"shinelon\",\"password\":null,\"birthday\":"+date.getTime()+"}";String result=mockMvc.perform(post("/user").content(content).contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andExpect(jsonPath("$.id").value(1)).andReturn().getResponse().getContentAsString();System.out.println(result);}

上面的代码传递了一段json字符串到后台,与表单提交不同的是,表单提交的参数会自动封装到用户实体类中,但是json字符串不会封装到实体类中,那怎么办呢?这时我们需要用到@RequestBody注解,在参数前加入这个参数,它会自动将json字符串按照映射到相应的字段中,并且当后端处理好业务后返回到前端的数据也会被处理成json字符串,这就给我们的开发带来了很好好处。

我们接着上面的场景,前端创建用户,后台来接收参数进行校验:
Controller层代码:

@PostMapping("/user")public User create(@Valid @RequestBody User user,BindingResult errors) {if(errors.hasErrors()) {errors.getAllErrors().forEach(error->System.out.println(error.getDefaultMessage()));;}user.setId(1);System.out.println(user.getId());System.out.println(user.getUsername());System.out.println(user.getPassword());System.out.println(user.getBirthday());return user;}

在上面的代码中,我们会看到@Valid注解和BindingResult errors,这就是我们的正题Hibernate Validation注解,当我们在参数user前面加上@Valid注解时,它就会在该类上自动校验相应的字段,当然User类中肯定需要对字段进行限制校验格式,下面我们会说明。我们再看看最后一个参数BindingResult,这个参数就是当你前台传递的数据校验不通过的时候处理一些错误信息的。如果没有BindingResult参数,当传递来的数据在@Valid注解中校验不通过的时候,它会直接返回错误的状态给用户,这也许和不友好,并且我们有些时候需要收集一些日志,比如记录你输入的一些错误信息,这时就需要用到BindingResult参数,它会在校验不通过的时候任然进入URL映射的方法中进行一些出来,这时我们可以打印具体的错误信息给用户以友好的展示,必须要说明的一点是,这个参数必须要在@Valid注解的参数的后面。

下面我们来看看在user类中的注解。

public class User {private int id;public String username;@NotBlankpublic String password;private Date birthday;//省略get,set方法

我们以密码不为空来校验数据,在之前的代码中,我们password设置为null,肯定校验失败,不过我们加了BindingResult参数,它会进入方法体中打印错误日志,下面是打印的错误日志:

上面是Hibernate Validation内部自带的默认错误信息,有时候需要设置自定义的错误信息,这时我们就可以使用message参数来指定。

public class User {private int id;public String username;//使用这个注解表示前台传回来的密码不能为空@NotBlank(message="密码不能为空")         //这个注解是hibernate validator中提供的开源项目public String password;@Past(message="生日的日期必须是过去的时间")      //表示生日必须是过去的时间private Date birthday;

下面是测试代码,Controller层的代码不变,还是上面的:

@Testpublic void whenPostSuccess() throws Exception {//一年以后的时间Date date=(Date) new java.util.Date(LocalDateTime.now().plusYears(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());System.out.println(date.getTime());String content="{\"username\":\"shinelon\",\"password\":null,\"birthday\":"+date.getTime()+"}";String result=mockMvc.perform(post("/user").content(content).contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andExpect(jsonPath("$.id").value(1)).andReturn().getResponse().getContentAsString();System.out.println(result);}

运行结果我们会发现打印了自定义的错误信息:

上面是Hibernate Validation几个简单的注解示例,下面这张图是Hibernate Validation的注解详解:

有些的读者可以自行试验上面的注解,这里就介绍到这里,下面我们来看看如何自定义注解。

二、自定义校验注解

有些场景Hibernate Validation不足以满足我们的需求,这时我们需要自定义注解来校验代码。
如何自定义注解呢?

首先,我们需要编写一个注解类:
MyValidator.java:

package cn.shinelon.annotation;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;@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyValidator {//自定义注解必须实现这三个属性String message();Class<?>[] groups() default{};Class<? extends Payload>[] payload() default{};}

然后编写该注解要处理校验的类
MyConstraintValidator.java:

/*** */
package cn.shinelon.annotation;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;import org.springframework.beans.factory.annotation.Autowired;import cn.shinelon.service.impl.HelloServiceImpl;/*** @author Shinelon**/
public class MyConstraintValidator implements ConstraintValidator<MyValidator, Object> {@Autowiredpublic HelloServiceImpl helloServiceImpl;@Overridepublic boolean isValid(Object arg0, ConstraintValidatorContext arg1) {helloServiceImpl.hello(" "+arg0);System.out.println(arg0);//返回true或者false表示是否校验成功return false;}//初始化@Overridepublic void initialize(MyValidator arg0) {System.out.println("my validator init");}}

该类实现了ConstraintValidator

public interface HelloService {public void hello(String name);
}

实现类:

@Service
public class HelloServiceImpl implements HelloService {/* (non-Javadoc)* @see cn.shinelon.service.HelloService#hello()*/@Overridepublic void hello(String name) {System.out.println("hello"+name);}
}

定义好注解后,我们将注解加载username字段上进行测试,因为注解中isValid方法返回的false,就是说校验失败。

    @MyValidator(message="这是一个自定义注解")public String username;

然后我们继续运行上面的单元测试,可以看到我们的自定义注解生效。

至此,我们就给大家介绍完Hibernate Validation校验注解的使用以及自定义注解来进行校验。欢迎留言讨论。


Hibernate Validation校验注解详解相关推荐

  1. Hibernate OneToMany等注解详解

    cascade属性: 指定级联操作的行为(可多选) CascadeType.PERSIST 级联新增(又称级联保存):   获取A对象里也同时也重新获取最新的B时的对象.即会重新查询数据库里的最新数据 ...

  2. Hibernate对象关系映射详解之一对多关系映射

    Hibernate对象关系映射详解之"一对多"关系映射 之前学习Hibernate框架的时候,对这七大关系映射一直是云里雾里的,虽然可以仿照写出代码,但是不能独立编写出来.鉴于工作 ...

  3. SpringMVC学习:控制层(Controller)基于注解详解

    文章目录 一.URL映射Controller的方法返回值 二.SpringMVC各类注解详解 (一) @Controller (二) @RequestMapping 1.基本用法 2. path属性或 ...

  4. zend framework php编码规范,Zend Framework常用校验器详解

    本文实例讲述了Zend Framework常用校验器.分享给大家供大家参考,具体如下: Date日期校验器 代码:<?php require_once 'Zend/Validate/Date.p ...

  5. mybatis注解详解

    mybatis注解详解 首 先当然得下载mybatis-3.0.5.jar和mybatis-spring-1.0.1.jar两个JAR包,并放在WEB-INF的lib目录下 (如果你使用maven,则 ...

  6. 开启注解缓存_Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解

    随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...

  7. Spring Boot注解详解

    文章目录 使用注解的优势 注解详解(配备了完善的释义) 注解列表如下 JPA注解 springMVC相关注解 全局异常处理 项目中具体配置解析和使用环境 使用注解的优势 采用纯java代码,不在需要配 ...

  8. 【SpringBoot 】SpringBoot注解详解

    [SpringBoot ]SpringBoot注解详解 一.注解(annotations)列表  @SpringBootApplication:包含了@ComponentScan.@Configura ...

  9. Spring data JPA 之 Jackson 在实体里面的注解详解

    8 Spring data JPA 之 Jackson 在实体里面的注解详解 经过前⾯课时的讲解,相信你已经对实体⾥⾯的 JPA 注解有了⼀定的了解,但是实际⼯作中你会发现实体⾥⾯不仅有 JPA 的注 ...

最新文章

  1. windows mongodb 安装
  2. 深入理解计算机系统:计算机系统概述
  3. Visual Studio 内存泄漏检测方法
  4. 【高校宿舍管理系统】第八章 学生管理和楼宇管理以及寝室管理
  5. speedbutton用法
  6. 用科学计算机log21 p x,山东理工大学数据结构期末 试题及答案
  7. GDB中应该知道的几个调试方法-转
  8. 使用IDEA 开发一个安卓HelloWorld的步骤
  9. Hadoop版本比较
  10. 速途在线沙龙11期:王通夫唯首次聚首共话SEO
  11. JAVA_抽象类和接口
  12. 主存、辅存、内存、外存、存储器:名词解释
  13. 《2018中国直销银行白皮书》发布 银行面临“颠覆式创新”
  14. Linux 系统注册系统服务流程
  15. schema list validator --python cerberus
  16. Silverlight WebOS案例2.0版本(基于Silverlight4开发的Web操作系统)
  17. three.js轨道控制器OrbitControls.js
  18. python修改单个文件
  19. 验后方差估计python_最大似然估计 (MLE) 最大后验概率(MAP)
  20. 爬虫登陆为啥子老被卡住?这些网站示例值得你拥有

热门文章

  1. oracle五种数据类型,Oracle数据类型
  2. python打印数据时,出现省略号,解决办法
  3. scipy球谐函数与电子云层
  4. matlab根轨迹临界稳定,根轨迹分析:根轨迹分析稳定性
  5. 武大版c语言程序设计习题 二维数组 简易学生成绩查询系统,《C语言程序设计》程设计报告.docx...
  6. 医疗转运和储存柜的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  7. Elan触控板双击右键失效 - 解决方案
  8. 淘宝API item_search_img - 按图搜索淘宝商品(拍立淘)
  9. [转贴]史上最牛女秘书
  10. 论文阅读 - Is Space-Time Attention All You Need for Video Understanding?