mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
JSR-303支持嵌套校验
This commit is contained in:
@@ -6,10 +6,14 @@ import com.gitee.sop.servercommon.message.ServiceErrorEnum;
|
||||
import com.gitee.sop.servercommon.message.ServiceErrorFactory;
|
||||
import com.gitee.sop.servercommon.param.validation.ValidationGroupSequence;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.ValidatorFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -23,6 +27,8 @@ public class ServiceParamValidator implements ParamValidator {
|
||||
private static final String COMMA = ",";
|
||||
private static Object[] EMPTY_OBJ_ARRAY = {};
|
||||
|
||||
private static final List<String> SYSTEM_PACKAGE_LIST = Arrays.asList("java.lang", "java.math");
|
||||
|
||||
private static javax.validation.Validator validator;
|
||||
|
||||
static {
|
||||
@@ -35,6 +41,11 @@ public class ServiceParamValidator implements ParamValidator {
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
// 先校验属性对象
|
||||
List<Object> fields = listObjectField(obj);
|
||||
if (!fields.isEmpty()) {
|
||||
fields.forEach(this::validateBizParam);
|
||||
}
|
||||
Set<ConstraintViolation<Object>> set = validator.validate(obj, ValidationGroupSequence.class);
|
||||
if (!CollectionUtils.isEmpty(set)) {
|
||||
ConstraintViolation<Object> oneError = set.iterator().next();
|
||||
@@ -43,6 +54,34 @@ public class ServiceParamValidator implements ParamValidator {
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> listObjectField(Object object) {
|
||||
List<Object> ret = new ArrayList<>();
|
||||
ReflectionUtils.doWithFields(object.getClass(), field -> {
|
||||
if (isCustomPackage(field.getType())) {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
ret.add(field.get(object));
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段类型所在package是否是自定义包
|
||||
* @param fieldType 指定的类型
|
||||
* @return true,是自定义的
|
||||
*/
|
||||
private boolean isCustomPackage(Class<?> fieldType) {
|
||||
if (fieldType.isPrimitive()) {
|
||||
return false;
|
||||
}
|
||||
Package aPackage = fieldType.getPackage();
|
||||
if (aPackage == null) {
|
||||
return false;
|
||||
}
|
||||
String packageName = aPackage.getName();
|
||||
return !SYSTEM_PACKAGE_LIST.contains(packageName);
|
||||
}
|
||||
|
||||
private RuntimeException getValidateBizParamException(String errorMsg) {
|
||||
String subCode = ServiceErrorEnum.ISV_PARAM_ERROR.getErrorMeta().getSubCode();
|
||||
String[] msgToken = errorMsg.split(EQ);
|
||||
|
@@ -11,7 +11,9 @@ import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
@@ -24,10 +26,17 @@ public class ValidatorTest extends TestCase {
|
||||
* 测试JSR-303注解校验顺序,校验顺序: Group1~GroupN
|
||||
*/
|
||||
public void testValidate() {
|
||||
serviceParamValidator.validateBizParam(new User("1", 1));
|
||||
serviceParamValidator.validateBizParam(new User("Jim", 30));
|
||||
}
|
||||
|
||||
|
||||
public void testField() {
|
||||
Manager manager = new Manager("Jim", 22);
|
||||
Store store = new Store("仓库A", manager);
|
||||
Goods goods = new Goods("Apple", new BigDecimal(50000), store);
|
||||
serviceParamValidator.validateBizParam(goods);
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
private static class User {
|
||||
@@ -36,7 +45,7 @@ public class ValidatorTest extends TestCase {
|
||||
@NotBlank(message = "NotBlank", groups = Group1.class)
|
||||
// 优先校验Group2
|
||||
// 可交换下面Group2,Group3,看下校验顺序
|
||||
@Length(min = 2, max = 20, message = "length must 10~20", groups = Group2.class)
|
||||
@Length(min = 2, max = 20, message = "length must 2~20", groups = Group2.class)
|
||||
@Pattern(regexp = "[a-zA-Z]*", message = "name must letters", groups = Group3.class)
|
||||
private String name;
|
||||
|
||||
@@ -45,4 +54,36 @@ public class ValidatorTest extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
static class Goods {
|
||||
@NotBlank(message = "商品名称不能为空")
|
||||
private String goodsName;
|
||||
|
||||
@Min(value = 1, message = "商品价格最小值为1")
|
||||
private BigDecimal price;
|
||||
|
||||
@NotNull(message = "仓库不能为空")
|
||||
private Store store;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
static class Store {
|
||||
@NotBlank(message = "库存名称不能为空")
|
||||
private String storeName;
|
||||
|
||||
@NotNull(message = "管理员不能为空")
|
||||
private Manager manager;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
static class Manager {
|
||||
@NotBlank(message = "管理员姓名不能为空")
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user