后台验证框架BeanValidate
一。在Maven中导入以下依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>6.0.13.Final</version>
</dependency>
二。在spring-context中加入以下配置
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="beanValidator" class="com.twgfs.commons.utils.BeanValidator">
<property name="validator" ref="validator" />
</bean>
注意: 上面 里面的class后面的 com.twgfs.commons.utils.BeanValidator 是Java验类包所在的位置
三。书写验证类
package com.twgfs.commons.utils;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.*;
public class BeanValidator {
@Autowired
private static Validator validator;
public static void setValidator(Validator validator) {
BeanValidator.validator = validator;
}
/**
*调用 JSR303 的 validate 方法, 验证失败时抛出 ConstraintViolationException.
*/
private static void validateWithException(Validator validator, Object object, Class<?>... groups) throws ConstraintViolationException {
Set constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) {
throw new ConstraintViolationException(constraintViolations);
}
}
/*辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 中为 List<message>.*/
private static List<String> extractMessage(ConstraintViolationException e) {
return extractMessage(e.getConstraintViolations());
}
/*辅助方法, 转换 Set<ConstraintViolation> 为 List<message>*/
private static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
List<String> errorMessages = new ArrayList<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.add(violation.getMessage());
}
return errorMessages;
}
//辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 为 Map<property, message>.
private static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
return extractPropertyAndMessage(e.getConstraintViolations());
}
//辅助方法, 转换 Set<ConstraintViolation> 为 Map<property, message>.
private static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
Map<String, String> errorMessages = new HashMap<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
}
return errorMessages;
}
//辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 为 List<propertyPath message>.
private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");
}
//辅助方法, 转换 Set<ConstraintViolations> 为 List<propertyPath message>.
private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) {
return extractPropertyAndMessageAsList(constraintViolations, " ");
}
//辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 为 List<propertyPath + separator + message>.
private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);
}
//辅助方法, 转换 Set<ConstraintViolation> 为 List<propertyPath + separator + message>.
private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations, String separator) {
List<String> errorMessages = new ArrayList<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage());
}
return errorMessages;
}
/**
* 服务端参数有效性验证
*
* @param object 验证的实体对象
* @param groups 验证组
* @return 验证成功:返回 null;验证失败:返回错误信息
*/
public static String validator(Object object, Class<?>... groups) {
try {
validateWithException(validator, object, groups);
} catch (ConstraintViolationException ex) {
List<String> list = extractMessage(ex);
list.add(0, "注意:");
// 封装错误消息为字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
String exMsg = list.get(i);
if (i != 0 ){
sb.append(String.format("%s. %s", i, exMsg)).append(list.size() > 1 ? " " : "");
} else {
sb.append(exMsg).append(list.size() > 1 ? " " : "");
}
}
return sb.toString();
}
return null;
}
}
注意: 这个类是异常捕获类,在类的最后添加了一个方法如下
public static String validator(Object object, Class<?>... groups) {
try {
validateWithException(validator, object, groups);
} catch (ConstraintViolationException ex) {
List<String> list = extractMessage(ex);
list.add(0, "注意:");
// 封装错误消息为字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
String exMsg = list.get(i);
if (i != 0 ){
sb.append(String.format("%s. %s", i, exMsg)).append(list.size() > 1 ? " " : "");
} else {
sb.append(exMsg).append(list.size() > 1 ? " " : "");
}
}
return sb.toString();//返回自己写的错误提示信息
}
return null;
}
这个是用来捕获验证报错然后进行相应的错误信息输出,这个方法会根据你在实体类上的注解将注解里的信息进行相应的输出
四。在需要进行后台验证实体类的字段上加上相应的注解,下面以我的实体类进行举列子
package com.twgfs.domain.entity;
import com.twgfs.commons.utils.RegexpUtils;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
@Data
public class User {
private Integer id;
@NotEmpty(message = "用户名不能为空")
private String username;
@NotEmpty(message = "密码不能为空")
private String password;
@NotEmpty(message = "电话号码不能为空")
@Pattern(regexp = RegexpUtils.PHONE, message = "手机格式不正确")
private String phone;
@NotEmpty(message = "邮箱不能为空")
@Pattern(regexp = RegexpUtils.EMAIL, message = "邮箱格式不正确")
private String email;
//数据库ORM会忽略该字段
// @Transient
// public int totalPage;
}
1. 以上的@NotEmpty是Validate中的非空验证在里main加上一句message="XXXXX"就会在输入的值为空的时候进行校验,如果为空那么就报错,报错后会被自己写的验证类进行捕获然后获取到相应的值,如果还需要进行正则验证那么可以在相应需要验证的字段上加上 @Pattern(regexp = RegexpUtils.EMAIL, message = “邮箱格式不正确”) 这个验证,但是这里的RegexpUtils.EMAIL是要进行匹配的正则类中的一个字段,匹配的正则类如下
package com.twgfs.commons.utils;
public class RegexpUtils {
/**
* 验证手机号
*/
public static final String PHONE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
/**
* 验证邮箱地址
*/
public static final String EMAIL = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";
/**
* 验证手机号
* @param phone
* @return
*/
public static boolean checkPhone(String phone) {
return phone.matches(PHONE);
}
/**
* 验证邮箱
* @param email
* @return
*/
public static boolean checkEmail(String email) {
return email.matches(EMAIL);
}
}
五.在进行了一系列的这些准备工作之后就可以在项目中使用了,这里就以我的注册模块的后台非空验证进行举列子
@RequestMapping("/regist")
public String regist(User user, Model model){
String result = BeanValidator.validator(user);
int flag = loginRegistService.ToRegist(user);
model.addAttribute("validatemsg",result);
System.out.println(result+"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
return "index";
}
- 这里的String result = BeanValidator.validator(user);就是将验证运用到了项目中
- 将前台注册的实体映射类user放到BeanValidator.validator(user)里就完成了后台验证
- 后台验证的实体类在根据注解进行相应的验证,如果发现不匹配,那么就会进行报错,然后错误会被写的验证类捕捉到在根据实体类上的message中的类容进行逐一输出,那么这里的result打印出来就是不匹配的