一个比较全面的博客:https://blog.csdn.net/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();
}