Hibernate Validator作用
1. 服务器是最后一道防线,需要检验前端传递的参数,普通的if判断冗余代码太多
2. Spring 4.0 开始支持 Bean Validation 功能。JSR-303 是 JavaEE 6 中的一项子规范,叫做 Bean Validation,官方使用Hibernate Validator。
Hibernate Validator使用
1. 导入hibernate-validator jar包
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
2. 配置 Validator bean对象
@Configuration
public class ValidatorConfig {
@Bean
public LocalValidatorFactoryBean validator(){
return new LocalValidatorFactoryBean();
}
}
3. 建立BeanValidator类,处理验证不通过后的逻辑
package com.wzh.myshop.commons.validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.*;
@Component
public class BeanValidator {
private static BeanValidator beanValidator;
@Autowired
private Validator validator;
@PostConstruct
private void init(){
beanValidator = this;
}
public static void setValidator(Validator validator) {
beanValidator.validator = validator;
}
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);
}
}
private static List<String> extractMessage(ConstraintViolationException e) {
return extractMessage(e.getConstraintViolations());
}
private static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
List<String> errorMessages = new ArrayList<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.add(violation.getMessage());
}
return errorMessages;
}
private static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
return extractPropertyAndMessage(e.getConstraintViolations());
}
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;
}
private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");
}
private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) {
return extractPropertyAndMessageAsList(constraintViolations, " ");
}
private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);
}
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;
}
public static String validator(Object object, Class<?>... groups) {
try {
validateWithException(beanValidator.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 ? "<br/>" : "");
} else {
sb.append(exMsg).append(list.size() > 1 ? "<br/>" : "");
}
}
return sb.toString();
}
return null;
}
}
4. example
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper=false)
public class User extends BaseEntity {
private Integer id;
@Length(min = 6,max = 20,message = "用户名长度必须介于6 - 20位之间")
private String username;
@JsonIgnore
private String password;
@Pattern(regexp = RegexpUtils.PHONE,message = "手机号码格式不正确")
private String mobileNumber;
@Pattern(regexp = RegexpUtils.EMAIL,message = "邮箱格式不正确")
private String email;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime ctime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime mtime;
}
@Override
public BaseResult save(User user) {
String validator = BeanValidator.validator(user);
if (validator != null) {
return BaseResult.not_ok(validator);
}
user.setPassword(StringUtils.isNotBlank(user.getPassword())?MyEAESUtil.jiami(user.getPassword()):null);
if (user.getId() == null) {
userMapper.insertSelective(user);
} else {
userMapper.updateByPrimaryKeySelective(user);
}
return BaseResult.ok("保存用户信息成功");
}
5. 页面显示
<div class="alert alert-danger alert-dismissible" th:if="${baseResult != null}">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<span th:utext="${baseResult.getMessage()}"></span>
</div>