Hibernate Bean Validator手动触发对Bean的字段校验

一个比较全面的博客:https://blog.youkuaiyun.com/xgblog/article/details/52548659

pom.xml,这里使用的SpringBoot的Web包,他默认包含了Hibernate的和Javax相关的校验包,也可以单独去依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
		<dependency>
			<groupId>joda-time</groupId>
			<artifactId>joda-time</artifactId>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<scope>provided</scope>
		</dependency>

VO实体:

package com.example.feild.validated.hibernate.manual;

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

import lombok.Data;

/**
 *
 * @author Hayashi
 * @date 2019-11-26
 */
@Data
public class User {

	@NotNull
	private String id;

	@Email(message = "邮箱格式不正确")
	private String email;

	@Size(min = 4, max = 16, message = "昵称长度为4~16个字符之间")
	private String nickName;

	@NotNull
	@Size(min = 8, max = 24, message = "密码长度为8~24个字符之间")
	private String pwd;

}

错误消息封装:

package com.example.feild.validated.hibernate.manual;

import java.text.MessageFormat;
import java.util.Map;

/**
 * @author Hayshi
 * @Description 实体校验结果
 */
public class ValidationResult {

	/**
	 * 是否有异常
	 */
	private boolean hasErrors;

	/**
	 * 异常消息记录
	 */
	private Map<String, String> errorMsg;

	/**
	 * 获取异常消息组装
	 *
	 * @return
	 */
	public String getMessage() {
		if (errorMsg == null || errorMsg.isEmpty()) {
			return "";
		}
		StringBuilder message = new StringBuilder();
		errorMsg.forEach((key, value) -> {
			message.append(MessageFormat.format("{0}:{1} \r\n", key, value));
		});
		return message.toString();
	}

	public boolean isHasErrors() {
		return hasErrors;
	}

	public void setHasErrors(boolean hasErrors) {
		this.hasErrors = hasErrors;
	}

	public Map<String, String> getErrorMsg() {
		return errorMsg;
	}

	public void setErrorMsg(Map<String, String> errorMsg) {
		this.errorMsg = errorMsg;
	}

	@Override
	public String toString() {
		return "ValidationResult{" + "hasErrors=" + hasErrors + ", errorMsg=" + errorMsg + '}';
	}
}

校验工具,里面的方法分为使用上面的校验错误封装结果和通过抛异常的两种方式

package com.example.feild.validated.hibernate.manual;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;

import org.hibernate.validator.HibernateValidator;
import org.springframework.util.CollectionUtils;

/**
 *
 * @author Hayashi
 * @date 2019-11-26
 */
public class ValidateUtils {

	private ValidateUtils() {
	}

	// 线程安全的,直接构建也可以,这里使用静态代码块一样的效果
	private static Validator validator;

	static {
		ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
		validator = factory.getValidator();
	}

	public static <T> void validate(T t) {
		Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
		if (constraintViolations.size() > 0) {
			StringBuilder validateError = new StringBuilder();
			for (ConstraintViolation<T> constraintViolation : constraintViolations) {
				validateError.append(constraintViolation.getMessage()).append(";");
			}

			throw new ValidationException(validateError.toString());
		}
	}

	public static <T> void validate1(T t) {
		Validator validator = Validation.byProvider(HibernateValidator.class).configure().failFast(false) // 为true,则有一个错误就结束校验
				.buildValidatorFactory().getValidator();

		Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);

		StringBuilder validateError = new StringBuilder();

		for (ConstraintViolation<T> constraintViolation : constraintViolations) {
			validateError.append(constraintViolation.getMessage()).append(";");
		}

		throw new ValidationException(validateError.toString());
	}

	// 自定义校验结果返回
	/**
	 * 校验实体,返回实体所有属性的校验结果
	 *
	 * @param obj
	 * @param <T>
	 * @return
	 */
	public static <T> ValidationResult validateEntity(T obj) {
		// 解析校验结果
		Set<ConstraintViolation<T>> validateSet = validator.validate(obj, Default.class);
		return buildValidationResult(validateSet);
	}

	/**
	 * 校验指定实体的指定属性是否存在异常
	 *
	 * @param obj
	 * @param propertyName
	 * @param <T>
	 * @return
	 */
	public static <T> ValidationResult validateProperty(T obj, String propertyName) {
		Set<ConstraintViolation<T>> validateSet = validator.validateProperty(obj, propertyName, Default.class);
		return buildValidationResult(validateSet);
	}

	/**
	 * 将异常结果封装返回
	 *
	 * @param validateSet
	 * @param <T>
	 * @return
	 */
	private static <T> ValidationResult buildValidationResult(Set<ConstraintViolation<T>> validateSet) {
		ValidationResult validationResult = new ValidationResult();
		if (!CollectionUtils.isEmpty(validateSet)) {
			validationResult.setHasErrors(true);
			Map<String, String> errorMsgMap = new HashMap<>();
			for (ConstraintViolation<T> constraintViolation : validateSet) {
				errorMsgMap.put(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
			}
			validationResult.setErrorMsg(errorMsgMap);
		}
		return validationResult;
	}

	public static <T> ValidationResult validateEntity1(T obj) {
		ValidationResult result = new ValidationResult();
		Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class);
		if (!CollectionUtils.isEmpty(set)) {
			result.setHasErrors(true);
			Map<String, String> errorMsg = new HashMap<String, String>();
			for (ConstraintViolation<T> cv : set) {
				errorMsg.put(cv.getPropertyPath().toString(), cv.getMessage());
			}
			result.setErrorMsg(errorMsg);
		}
		return result;
	}

	public static <T> ValidationResult validateProperty1(T obj, String propertyName) {
		ValidationResult result = new ValidationResult();
		Set<ConstraintViolation<T>> set = validator.validateProperty(obj, propertyName, Default.class);
		if (!CollectionUtils.isEmpty(set)) {
			result.setHasErrors(true);
			Map<String, String> errorMsg = new HashMap<String, String>();
			for (ConstraintViolation<T> cv : set) {
				errorMsg.put(propertyName, cv.getMessage());
			}
			result.setErrorMsg(errorMsg);
		}
		return result;
	}

}

Controller里面就可以手动触发校验,当然其他地方也同样可以使用

@RequestMapping(method = RequestMethod.POST, path = "/testUserV", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public String testUserV(@RequestBody User user) {
		ValidateUtils.validate1(user);
		// ValidationResult validateEntity = ValidateUtil.validateEntity(user);
		// ValidationResult validateEntity = ValidateUtil.validateProperty(user, "pwd");

		return null;// validateEntity.toString();
	}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值