package com.runachina.sc.designer.domain.validator; import com.runachina.cloud.starter.base.exception.RestResultException; import com.runachina.cloud.starter.base.rest.ResultStatus; import com.runachina.sc.designer.domain.validator.annotations.UniqueField; import com.runachina.sc.designer.domain.validator.utils.MessageUtil; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; public class UniqueFieldValidator implements ConstraintValidator<UniqueField, Collection> { private String[] fieldNames; @Override public void initialize(UniqueField constraintAnnotation) { this.fieldNames = constraintAnnotation.filedNames(); ConstraintValidator.super.initialize(constraintAnnotation); } /** * getDeclaredField()和 getField() 方法都是获取字段的 * getField 只能获取 public 的,包括从父类继承来的字段。 * getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true)) * 因此在获取父类的私有属性时,要通过getSuperclass的之后再通过getDeclaredFiled获取 */ @Override public boolean isValid(Collection valueList, ConstraintValidatorContext constraintValidatorContext) { Map<String, String> valuesMap = new HashMap<>(); String fields = String.join("&", fieldNames); List<String> methodNames = field2method(fieldNames); for (Object value : valueList) { String values = getValues(value, methodNames); if (valuesMap.containsKey(values)) { String message = "字段【" + fields + "】的值:" + values + " 重复"; MessageUtil.setMessage(constraintValidatorContext, message); return false; } valuesMap.put(values, ""); } return true; } /** * 获取属性的值 */ private String getValues(Object o, List<String> methodNames) { Class<?> aClass = o.getClass(); List values = new ArrayList(); // 获取方法的返回值 for (String methodName : methodNames) { try { Method method = aClass.getMethod(methodName); values.add(method.invoke(o)); } catch (NoSuchMethodException e) { throw new RestResultException(ResultStatus.ILLEGAL_ARGUMENT, "类【" + aClass.getName() + "】中找不到【" + methodName + "】方法"); } catch (IllegalAccessException e) { throw new RestResultException(ResultStatus.ILLEGAL_ARGUMENT, "类【" + aClass.getName() + "】方法【" + methodName + "】拒绝访问"); } catch (InvocationTargetException e) { throw new RestResultException(ResultStatus.ILLEGAL_ARGUMENT, "类【" + aClass.getName() + "】执行方法【" + methodName + "】异常"); } } return String.join("&", values); } /** * 字段名转get方法名 * 因为父类私有属性的值获取不到,得采取调用public的get方法获取属性值 */ private List<String> field2method(String[] fieldNames) { List<String> methodNames = new ArrayList(); for (String fieldName : fieldNames) { methodNames.add("get" + upperFirst(fieldName)); } return methodNames; } /** * 首字母大写 */ private String upperFirst(String name) { return name.substring(0, 1).toUpperCase() + name.substring(1); } }
标签:String,自定义,List,校验,private,methodNames,values,import From: https://www.cnblogs.com/LcxSummer/p/16708379.html