在日常工作中,我们一般在 Controller层进行对 DTO 文件进行校验,但有时在Excel文件导入、List<DTO> userDTOList 批量更新功能中,对 DTO 文件的校验需要放到 Service层。在这里,我写了几个校验文件,推荐使用 ValidatorUtil3.java 文件进行对 DTO 文件进行校验。
ValidatorUtil3.java 文件,对 DTO 文件进行格式校验。
package com.moon.util;
import com.moon.constant.Constant;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.*;
/**
* 描述信息:DTO、List<DTO>数据校验类
*
* @author moon
* @version 1.0
* @date 2023/2/3 13:06
*/
public class ValidatorUtil3 {
private static final Validator VALIDATOR;
static {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
VALIDATOR = factory.getValidator();
}
/**
* 校验单个实体类型
*
* @param obj
* @param verfiyGroup
* @return
* @author moon 2023/2/8 14:56
*/
public static String validation(Object obj, Class[] verfiyGroup) {
Set<ConstraintViolation<Object>> set = null;
if (verfiyGroup != null) {
set = VALIDATOR.validate(obj, verfiyGroup);
} else {
set = VALIDATOR.validate(obj, new Class[Constant.Digital.ZERO]);
}
return set != null && set.size() > 0 ? getValidateErrorMsg(set) : null;
}
/**
* 将实体类中的错误信息拼接后返回。
*
* @param set
* @return
*/
private static String getValidateErrorMsg(Set<ConstraintViolation<Object>> set) {
StringBuilder builder = new StringBuilder();
Iterator var2 = set.iterator();
while (var2.hasNext()) {
ConstraintViolation constraintViolation = (ConstraintViolation) var2.next();
builder.append(constraintViolation.getMessage()).append(Constant.CommonlySymbols.SEMICOLON);
}
return builder.toString();
}
}
UserParamDTO.java 文件
package com.moon.dto;
import com.alibaba.fastjson2.annotation.JSONField;
import com.moon.constant.ValidGroup;
import com.moon.vo.VerifyMode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@Data
@AllArgsConstructor
@ToString
@ApiModel("用户表入参DTO类")
public class UserParamDTO extends VerifyMode implements Serializable {
private static final long serialVersionUID = 8473293468203956317L;
@ApiModelProperty(value = "用户编号ID")
@NotNull(message = "主键ID不能为空!", groups = {ValidGroup.Update.class})
private Long id;
@ApiModelProperty(value = "用户姓名")
@NotBlank(message = "姓名不能为空!", groups = {ValidGroup.Insert.class})
@Length(message = "姓名最多不能超过{max}个字!", max = 6, groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
private String name;
@ApiModelProperty(value = "用户年龄")
@NotNull(message = "年龄不能为空!", groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
@Range(message = "年龄最小不低于{min}岁,最大不能超过{max}岁!", min = 0, max = 120, groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
private Integer age;
@ApiModelProperty(value = "创建时间")
@JSONField(format="yyyy-MM-dd HH:mm:ss") // fastjson中处理时间字段的注解.
@NotNull(message = "创建时间不能为空!", groups = {ValidGroup.Insert.class})
private Date createDate;
// 非数据库表字段
@ApiModelProperty(value = "用户姓名集合")
@Size(message = "姓名最少不低于{min}个,最多不超过{max}", min = 0, max = 10, groups = {ValidGroup.Check.class})
private List<String> nameList;
// --------------------------- get/set、构造函数、toString() 函数 ---------------------------
/**
* 无参构造函数
*/
public UserParamDTO() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
Service层批量更新函数
/**
* 批量更新 User 信息
*
* @param paramDTOList
* @return
*/
@Override
public Boolean updateUserList(List<UserParamDTO> paramDTOList) {
// 这里,对数据进行校验。
// 数据校验,方式一
// ValidatorUtil.validateParams(paramDTOList, Constant.HttpMessage.HTTP_500_CODE, ValidGroup.Update.class);
// 数据校验,方式二,推荐。
for (UserParamDTO paramDTO : paramDTOList) {
String errorMsg = ValidatorUtil3.validation(paramDTO, new Class[]{ValidGroup.Update.class});
paramDTO.setErrorMsg(errorMsg);
}
List<String> errorMsgList = paramDTOList.stream().map(UserParamDTO::getErrorMsg).sorted().collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(errorMsgList)) {
System.out.println("paramDTOList为:" + JSON.toJSONString(paramDTOList));
throw new CommonException(Constant.HttpMessage.HTTP_500_CODE, errorMsgList.stream().collect(Collectors.joining()));
}
List<User> userList = new ArrayList<>();
for (UserParamDTO paramDTO : paramDTOList) {
User user = new User();
BeanUtils.copyProperties(paramDTO, user);
userList.add(user);
}
int result = userMapper.updateBatch(userList);
return result > Constant.Digital.ZERO;
}
项目启动后,在 Knife4j 中输入测试用例,返回值如下图一所示。
[
{
"age": 20,
"createDate": "",
"id": 1017,
"name": "狗狗30000003",
"nameList": [],
"errorMsg": ""
},
{
"age": 900450,
"createDate": "",
"id": 1018,
"name": "猫猫2233445566",
"nameList": [],
"errorMsg": ""
}
]
![](https://img-blog.csdnimg.cn/img_convert/a4ae9d29c0b68d5f4f624b78f5a717c6.png)
图一
本篇文章Demo案例:springboot-demo 项目 ,Controller层入口函数URL为:/user2/batchUpdateUser