validator是用来校验参数使用!

一般来说校验参数的工作可以放在前端去执行,但是假如有人不经过前端直接调用后端的接口呢?很可能就出现非法数据而导致一些问题,所有服务端也要做数据的校验。

前端校验是为了提高用户的体验度,后端校验则是为了保证数据的安全性。

校验参数基本上是一个体力活,而且冗余代码繁多,也影响代码的可读性,我们需要一个比较优雅的方式来解决这个问题。Hibernate Validator 框架刚好解决了这个问题,可以以很优雅的方式实现参数的校验,让业务代码和校验逻辑分开,不再编写重复的校验逻辑。

hibernate-validator优势:  1.验证逻辑与业务逻辑之间进行了分离,降低了程序耦合度

2.统一且规范的验证方式,无需你再次编写重复的验证代码

             3.你将更专注于你的业务,将这些繁琐的事情统统丢在一边

hibernate-validator的maven坐标:

其实spring-boot-starter-web中已经依赖了hibernate-validator

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>

hibernate-validator提供的校验方式为在类的属性上加入相应的注解来达到校验的目的。hibernate-validator提供的用于校验的注解如下:

注解 说明
@AssertTrue 用于boolean字段,该字段只能为true
@AssertFalse 用于boolean字段,该字段只能为false
@CreditCardNumber 对信用卡号进行一个大致的验证
@DecimalMax 只能小于或等于该值
@DecimalMin 只能大于或等于该值
@Email 检查是否是一个有效的email地址
@Future 检查该字段的日期是否是属于将来的日期
@Length(min=,max=) 检查所属的字段的长度是否在min和max之间,只能用于字符串
@Max 该字段的值只能小于或等于该值
@Min 该字段的值只能大于或等于该值
@NotNull 不能为null
@NotBlank 不能为空,检查时会将空格忽略
@NotEmpty 不能为空,这里的空是指空字符串
@Pattern(regex=) 被注释的元素必须符合指定的正则表达式
@URL(protocol=,host,port) 检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件

入门案例

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.xiaoteng</groupId>
<artifactId>validator-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--
spring-boot-starter-web中已经依赖了hibernate-validator
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

实体类

package com.entity;

import lombok.Data;
import org.hibernate.validator.constraints.Length; import javax.validation.constraints.*; /**
* @author xiaozhuang
* @date 2022年02月26日 14:03
*/
@Data
public class User {
@NotNull(message = "用户id不能为空(null)")
private int id;
@NotEmpty(message = "用户名不能为空")
@Length(max = 50, message = "用户名长度不能超过50")
private String userName;
@Max(value = 100, message = "年龄最大为100")
@Min(value = 18, message = "年龄最小为18")
private int age;
@Pattern(regexp = "[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$",
message = "邮箱格式不正确")
private String email; }

controller

package com.controller;

import com.entity.User;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotBlank; /**
* @author xiaozhuang
* @date 2022年02月26日 14:13
*/
@RestController
@RequestMapping("/user")
@Validated //开启校验功能
public class UserController {
//简单数据类型校验
@RequestMapping("/byId")
public String delete(@NotBlank(message = "id不能为空") String id){
System.out.println("id为..." + id);
return "OK";
}
//对象属性校验
@RequestMapping("/save")
public String save(@Validated User user){
System.out.println("save..." + user);
return "OK";
}
}
package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import javax.swing.*; /**
* @author xiaozhuang
* @date 2022年02月26日 14:18
*/
@SpringBootApplication
public class ValidatorApp {
public static void main(String[] args) {
SpringApplication.run(ValidatorApp.class,args);
}
}

启动项目,然后访问。

首先是简单类型的校验:

1.正常访问

2.不传id

再看控制台报错

接下来是实体类的校验:

1.传一个id的报错

这里只有三个都传了对于的值才不会报错。并且用了它有几个问题需要处理。

1.页面返回错误也不合适,需要做一个全局的异常处理

2.这里的参数校验,特别是对象时,当已经有一个参数校验不通过了以后,其他的参数也就不需要再校验了,就应该直接返回错误信息了,而不是一个没有通过,其他的还接着校验,需要做一个指定校验时使用快速失败返回模式

全局异常处理: 这里只是针对validator的异常处理

package com.config;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set; /**
* 全局异常处理
*/
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
public class ExceptionConfiguration {
@ExceptionHandler({ConstraintViolationException.class,BindException.class})
public String validateException(Exception ex, HttpServletRequest request) {
ex.printStackTrace();
String msg = null;
if(ex instanceof ConstraintViolationException){
ConstraintViolationException constraintViolationException =
(ConstraintViolationException)ex;
Set<ConstraintViolation<?>> violations =
constraintViolationException.getConstraintViolations();
ConstraintViolation<?> next = violations.iterator().next();
msg = next.getMessage();
}else if(ex instanceof BindException){
BindException bindException = (BindException)ex;
msg = bindException.getBindingResult().getFieldError().getDefaultMessage();
}
return msg;
}
}

此时页面返回的友好提示是这样的

指定校验时使用快速失败返回模式:  这里并没有使用@Configuration注解,而是使用自定义注解,在需要使用它的类上面用,更加灵活。

package com.config;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory; /**
* @author xiaozhuang
* @date 2022年02月26日 14:46
*/
//@Configuration 使用它就是所有的都会经过这里
public class ValidatorConfiguration {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory =
Validation.byProvider(HibernateValidator.class)
.configure()
//快速失败返回模式
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
return validatorFactory.getValidator();
} /**
* @return 开启快速返回
* 如果参数校验有异常,直接抛异常,不会进入到 controller,使用全局异常拦截进行拦截
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor =
new MethodValidationPostProcessor();
/**设置validator模式为快速失败返回*/
postProcessor.setValidator(validator());
return postProcessor;
}
}
package com.config;

import org.springframework.context.annotation.Import;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 在启动类上添加该注解来启动表单验证功能---快速失败返回模式
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ValidatorConfiguration.class) // 代表导入失败快速返回的配置类
public @interface EnableFormValidator {
}

这时我们把它可以加在启动类上,也可以放在某个单独的controller类上面。

再看效果:

就只校验了age,发生错误就直接返回了,没有再对userName进行校验了。

hibernate-validator的基本使用的更多相关文章

  1. Hibernate Validator验证标签说明

    Hibernate Validator是JSR-303的一个实现. 在FormBean里添加Hibernate Validator的注解,与定义一个校验类的做法相比.注解更加简洁.灵活. Bean V ...

  2. 非WEB项目中引入Hibernate Validator

    前言: 网上一些朋友分享了关于hibernate-validator的使用方法,但是不是缺少关联库信息,就是提供的参考代码中缺少自定类. 希望我这一篇博客能够让你顺利的跑出预期的结果. 如果有错,可以 ...

  3. Hibernate Validator

    http://docs.jboss.org/hibernate/validator/4.2/reference/zh-CN/html_single/#example-group-interfaces

  4. spring boot 1.4默认使用 hibernate validator

    spring boot 1.4默认使用 hibernate validator 5.2.4 Final实现校验功能.hibernate validator 5.2.4 Final是JSR 349 Be ...

  5. Hibernate validator验证

    spring-mvc配置 <mvc:annotation-driven validator="validator" /> <bean id="valid ...

  6. springMvc 支持hibernate validator

    SpringMVC 支持Hibernate Validator 发表于9个月前(2014-08-04 11:34)   阅读(1780) | 评论(0) 11人收藏此文章, 我要收藏 赞0 5月23日 ...

  7. SpringMVC利用Hibernate validator做字段验证

    1.添加Hiberbate validator相关的jar包 2.字需要验证的formbean 上添加验证的注解,内置注解有: dBean Validation 中内置的 constraint @Nu ...

  8. JSR303的数据校验-Hibernate Validator方式实现

    1.什么是JSR303? JSR303是java为bean数据合法性校验所提供的一个标准规范,叫做Bean Validation. Bean Validation是一个运行时的数据校验框架,在验证之后 ...

  9. org.hibernate.validator.constraints.NotBlank' validating type 'java.lang.Integer

    使用hibernate时,在save方法时,报了:org.hibernate.validator.constraints.NotBlank' validating type 'java.lang.In ...

  10. Hibernate Validator 6.0.9.Final - JSR 380 Reference Implementation: Reference Guide

    Preface Validating data is a common task that occurs throughout all application layers, from the pre ...

随机推荐

  1. Python入门-第一行代码到多行代码

    不管学啥语言,开始的第一行代码都是: print("hello word") 回车之后,就代表你正式进入代码的世界! 如果报错,恭喜你获得第一个书写bug,请检查单词拼写,双引号, ...

  2. Spring Boot-@Conditional注解以及衍生注解@ConditionalOnBean

    @Conditional:判断@Conditional指定的条件是否成立,如果成立才会给容器中添加组件,配置类里面的内容才会生效 我们发现有很多的自动配置类,但是这些自动配置类都有指定的条件,必须满足 ...

  3. Servlet实现登录注册

    1.注册页面register.html <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  4. keytools命令生成证书

    平时开发中可以使用keytools命令生成证书,一般常用格式为: keytool -genkey -alias tzzxxt -keyalg RSA -keypass 123456 -validity ...

  5. 3.初识Java

    一.Java特性和优势 简单性 面向对象 可移植性 高性能 分布式 动态性 多线程 安全性 健壮性 二.Java三大版本 一次编写到处运行 JavaSE:标准版(桌面程序,控制台开发) JavaME: ...

  6. JavaWeb学习day7-Response初学3(重定向)

    重定向:web资源收到客户端请求后,通知客户端去访问另外一个web资源 1 protected void doGet(HttpServletRequest req, HttpServletRespon ...

  7. 2021牛客暑期多校训练营3 J 思维

    传送门 J-Counting Triangles_2021牛客暑期多校训练营3 (nowcoder.com) 题目 Goodeat finds an undirected complete graph ...

  8. HCIE笔记-第七节-ICMP+ARP

    ICMP重定向 作用:解决网络中的次优路径 触发:当某一个设备收到一个数据,进行转发时发现还要从该接口进行转发,于是触发ICMP重定向. 报文:Type=5,Code=0 ARP -- 地址解析协议 ...

  9. 2021.11.03 P6175 无向图的最小环问题

    2021.11.03 P6175 无向图的最小环问题 P6175 无向图的最小环问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 给定一张无向图,求图中一个至少包含 33 ...

  10. python中常用内置函数和关键词

    Python 常用内置函数如下: Python 解释器内置了很多函数和类型,您可以在任何时候使用它们.以下按字母表顺序列出它们. 1. abs()函数 返回数字的绝对值. print( abs(-45 ...