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. uni-app中遇到的跳转问题

    最近在使用uni-app时,遇到的一个问题,使用uni.navigateTo跳转时在H5端是可以的,在小程序端报 fail webview count limit exceed 这个错,解决办法如下: ...

  2. python---用顺序表实现栈

    class Stack(object): """栈, 存放数据的一种容器, 后进先出""" def __init__(self): self ...

  3. 攻防世界 favorite_number

    favorite_number 进入环境得到源码 <?php //php5.5.9 $stuff = $_POST["stuff"]; $array = ['admin', ...

  4. 序列化器中钩子函数源码分析、many关键字源码分析

    局部钩子和全局钩子源码分析(2星) # 入口是 ser.is_valid(),是BaseSerializer的方法 # 最核心的代码 self._validated_data = self.run_v ...

  5. jquery 日期插件datePicker使用

    1.将下载下来的DatePicker压缩包解压后整个放入项目中,不可只引入js和css 2.在html中指定input位置加上class="Wdate"(默认样式不加也可正常显示) ...

  6. Mybatis项目无法初始化异常

    该异常是Maven资源导出时出错,.xml文件或者.properties文件不能正常导出所致,最简单的办法就是在目标文件上复制粘贴一份.xml文件或者是.properties文件: 但是实际应用的过程 ...

  7. Codeforces Round #671 (Div. 2) B. Stairs 难度1200

    题目链接: Problem - 1419B - Codeforces 题目 题意 给x个格子,你可以用这x个格子去拼成楼梯 好的楼梯的要求如下: 1. 第n列有n个格子 2. 这个楼梯的所有格子可以被 ...

  8. Flex 的 多种对齐属性

    1. html 结构 <div id="container"> <div class="item item-1"> <h3> ...

  9. Effective HPA:预测未来的弹性伸缩产品

    作者 胡启明,腾讯云专家工程师,专注 Kubernetes.降本增效等云原生领域,Crane 核心开发工程师,现负责成本优化开源项目 Crane 开源治理和弹性能力落地工作. 余宇飞,腾讯云专家工程师 ...

  10. MySQL基础之写表(创建表)

    我的博客 工具 市面上的SQL可视化工具不少,我一般常用的主要就是这两个. 当然,IDEA也是集成了数据库可视化功能的.除了这些,还有DBeaver.SQLyog等等. 我比较喜欢DataGrip,我 ...