前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot 校验器(Validator)

Springboot 校验器(Validator)

作者头像
netkiller old
发布2020-05-07 17:38:22
1.9K0
发布2020-05-07 17:38:22
举报
文章被收录于专栏:NetkillerNetkiller

节选自《Netkiller Spring Cloud 手札》

3.7. 校验器(Validator)

常见的校验注解

@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式

Hibernate Validator提供的校验注解:
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内	

3.7.1. 常规用法

3.7.1.1. 定义校验器

package web.domain;

import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

	private Long id;

	@NotNull(message = "用户账号不能为空")
	@Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
	private String username;

	@NotNull(message = "用户密码不能为空")
	@Size(min = 6, max = 8, message = "密码长度必须是6-8个字符")
	private String password;

	@NotNull(message = "用户邮箱不能为空")
	@Email(message = "邮箱格式不正确")
	private String email;

	// 不允许为空,并且年龄的最小值为18
	@NotNull
	@Min(18)
	private Integer age;

	public User() {
		// TODO Auto-generated constructor stub
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", age=" + age + "]";
	}

}

3.7.1.2. 获取 BindingResult 结果

package web.restful;

import javax.validation.Valid;

import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import web.domain.User;

@RestController
@RequestMapping("/restful")
public class TestRestController {

	@RequestMapping("/test")
	public String home() {
		return "OK";
	}

	@PostMapping("/validation")
	public String addUser(@RequestBody @Valid User user, BindingResult bindingResult) {
		// 如果有参数校验失败,返回错误信息
		if (bindingResult.hasErrors()) {
			System.out.println(user.toString());
			System.out.println(bindingResult.getErrorCount());
			System.out.println(bindingResult.getAllErrors());
		}

		for (ObjectError error : bindingResult.getAllErrors()) {
			return error.getDefaultMessage();
		}
		return user.toString();
	}

}

3.7.1.3. 测试校验效果

neo@MacBook-Pro-Neo ~/workspace/Management % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkillermsn.com"}' curl http://localhost:8080/restful/validation
邮箱格式不正确

neo@MacBook-Pro-Neo ~/workspace/Management % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkiller@msn.com"}' curl http://localhost:8080/restful/validation
must not be null

neo@MacBook-Pro-Neo ~/workspace/Management % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkiller@msn.com", "age":20}' curl http://localhost:8080/restful/validation
User [id=100000, username=netkiller, password=123456, email=netkiller@msn.com, age=20]

3.7.2. 自定义注解

下面实现一个手机号码检查的注解。

@Retention :用来说明该注解类的生命周期。它有以下三个参数:
RetentionPolicy.SOURCE : 注解只保留在源文件中
RetentionPolicy.CLASS : 注解保留在class文件中,在加载到JVM虚拟机时丢弃
RetentionPolicy.RUNTIME : 注解保留在程序运行期间,此时可以通过反射获得定义在某个类上的所有注解。

@Target : 用来说明该注解可以被声明在那些元素之前。
ElementType.TYPE:说明该注解只能被声明在一个类前。
ElementType.FIELD:说明该注解只能被声明在一个类的字段前。
ElementType.METHOD:说明该注解只能被声明在一个类的方法前。
ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。
ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。
ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。
ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。
ElementType.PACKAGE:说明该注解只能声明在一个包名前。

@Constraint来限定自定义注解的方法

3.7.2.1. 定义校验器注解接口

package cn.netkiller.web.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;

import javax.validation.Constraint;
import javax.validation.Payload;

import cn.netkiller.web.annotation.impl.MobileValidator;

@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MobileValidator.class)
@Documented
// 注解的实现类。
public @interface Mobile {
	// 校验错误的默认信息
	String message() default "手机号码格式不正确!";

	// 是否强制校验
	boolean isRequired() default true;

	Class<?>[] groups() default {};

	Class<? extends Payload>[] payload() default {};
}

3.7.2.2. 实现接口

package cn.netkiller.web.annotation.impl;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.springframework.util.StringUtils;

import cn.netkiller.web.annotation.Mobile;

public class MobileValidator implements ConstraintValidator<Mobile, String> {

	public MobileValidator() {
		// TODO Auto-generated constructor stub
	}

	private boolean required = false;

	@Override
	public void initialize(Mobile constraintAnnotation) {
		required = constraintAnnotation.isRequired();
	}

	@Override
	public boolean isValid(String phone, ConstraintValidatorContext constraintValidatorContext) {
		Pattern mobile_pattern = Pattern.compile("1\\d{10}");
		// System.out.println(phone);
		// 是否为手机号的实现
		if (required) {
			if (StringUtils.isEmpty(phone)) {
				return false;
			}
			Matcher m = mobile_pattern.matcher(phone);
			return m.matches();

		} else {
			return StringUtils.isEmpty(phone);
		}
	}
}			

3.7.2.3. 注解用法

package cn.netkiller.web.domain;

import java.util.Date;

import javax.validation.constraints.Email;
import javax.validation.constraints.Future;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import cn.netkiller.web.annotation.Mobile;

public class User {

	private Long id;

	@NotNull(message = "用户账号不能为空")
	@Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
	private String username;

	@NotNull(message = "用户密码不能为空")
	@Size(min = 6, max = 8, message = "密码长度必须是6-8个字符")
	private String password;

	@NotNull(message = "用户邮箱不能为空")
	@Email(message = "邮箱格式不正确")
	private String email;

	// 这里是新添加的注解奥
	@Mobile(message = "手机号码格式错误!!!")
	private String phone;

	// 不允许为空,并且年龄的最小值为18
	@NotNull
	@Min(18)
	private Integer age;

	@Future
	private Date createTime;

	public User() {
		// TODO Auto-generated constructor stub
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", phone=" + phone + ", age=" + age + "]";
	}

}			

3.7.2.4. 测试注解

neo@MacBook-Pro-Neo ~ % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkiller@msn.com", "age":20, "phone":"BB"}' curl http://localhost:8080/restful/validation
手机号码格式错误!!!

neo@MacBook-Pro-Neo ~ % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkiller@msn.com", "age":20, "phone":"2433"}' curl http://localhost:8080/restful/validation
手机号码格式错误!!!

neo@MacBook-Pro-Neo ~ % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkiller@msn.com", "age":20, "phone":"130"}' curl http://localhost:8080/restful/validation
手机号码格式错误!!!%


neo@MacBook-Pro-Neo ~ % curl -H "Content-Type: application/json" -d '{"id":100000, "username":"netkiller", "password":"123456", "email":"netkiller@msn.com", "age":20, "phone":"13022223333"}' curl http://localhost:8080/restful/validation
User [id=100000, username=netkiller, password=123456, email=netkiller@msn.com, phone=13022223333, age=20]%			
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Netkiller 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.7. 校验器(Validator)
    • 3.7.1. 常规用法
      • 3.7.1.1. 定义校验器
      • 3.7.1.2. 获取 BindingResult 结果
      • 3.7.1.3. 测试校验效果
    • 3.7.2. 自定义注解
      • 3.7.2.1. 定义校验器注解接口
      • 3.7.2.2. 实现接口
      • 3.7.2.3. 注解用法
      • 3.7.2.4. 测试注解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档