根据注解 SealAuthId 去查找要标记位的属性,并修改其值
如果直属属性中没有修改的属性,而是在其子孙属性中,则通过 SealAuthId (CONTAIN) 引导程序到子属性中去查找
直到找到标记 SealAuthId (AUTH_ID) 的属性,执行修改方法
待处理对象
@Data
public class YcDTO {
@SealAuthId(type = SealAuthId.CONTAIN)
@Valid
@NotEmpty(message = "信息列表[dataList]不能为空")
private List<YcSignatories> dataList;
}
子对象
@Data
public class YcSignatories {
@SealAuthId
@NotBlank(message = "编码[sealId]不能为空")
private String sealId;
}
/**
* 找到dto对象中注解标记的 SealAuthId(AUTH_ID) 并执行方法 function
* @param dto 待查找的对象
* @param function 找到注解标记后执行的方法
*/
public static void findAnnotationAndDo(Object dto, Function function) {
if (Objects.isNull(dto)){
log.debug("dto is NULL");
return;
}
Class<?> parameterObjectClass = dto.getClass();
Field[] fields = parameterObjectClass.getDeclaredFields();
for (Field field : fields){
SealAuthId sealAuthId = AnnotationUtils.findAnnotation(field, SealAuthId.class);
if (Objects.nonNull(sealAuthId)){
log.debug("查找到注解@SealAuthId[{}]", field.getName());
if (SealAuthId.AUTH_ID.equals(sealAuthId.type())){
annotateParameterDo(dto, field, function);
} else if (SealAuthId.CONTAIN.equals(sealAuthId.type())){
annotateContainSearch(dto, field, function);
}
}
}
}
/**
* 查找到包含注解的对象,准备进行下一步查找
* 在标记 CONTAIN 属性中继续查找,直到查找到标记 AUTH_ID
* @param dto 待查找的对象
* @param function 找到注解标记 AUTH_ID 后执行的方法
* @param field 注解标记为“CONTAIN”的属性
*/
private static void annotateContainSearch(Object dto, Field field, Function function) {
try {
if (!field.isAccessible()){
field.setAccessible(true);
}
Object objContain = field.get(dto);
if (Objects.isNull(objContain)){
log.debug("{} is NULL, continue.", field.getName());
return;
}
// 属性有值
if (Collection.class.isAssignableFrom(field.getType())){
log.debug("{} is collection", field.getName());
Iterator iterator = ((Collection) objContain).iterator();
while (iterator.hasNext()){
// 遍历查询集合中的对象中的注解
// 因为是从请求参数中反序列化得来的,暂时不考虑循环引用问题
findAnnotationAndDo(iterator.next(), function);
}
} else {
log.debug("{} is obj", field.getName());
// 因为是从请求参数中反序列化得来的,暂时不考虑循环引用问题
findAnnotationAndDo(objContain, function);
}
} catch (IllegalAccessException e) {
log.error(e.getMessage());
}
}
/**
* 查找到注解标记 AUTH_ID 的属性,执行操作
* @param dto 待查找的对象
* @param function 找到注解标记 AUTH_ID 后执行的方法
* @param field 注解标记为 AUTH_ID 的属性
*/
private static void annotateParameterDo(Object dto, Field field, Function function) {
if (!field.isAccessible()){
field.setAccessible(true);
}
try {
// 原值
Object localValue = field.get(dto);
if (Objects.nonNull(function)){
// 修改值的方法效用
Object apply = function.apply(localValue);
// 通过对象的setter方法重置属性的值
field.set(dto, apply);
log.info("修改注解标记的{}: {} => {}", field.getName(), localValue, apply);
}
} catch (IllegalAccessException e) {
log.error(e.getMessage());
}
}
public void defaultBind(Object[] params, SealBind sealBind){
Object param = params[0];
SealAuthUtils.findAnnotationAndDo(param, sealCode -> {
if (Objects.nonNull(sealCode) && sealCode instanceof String){
return findSealCodeByAuthId((String) sealCode, sealBind);
}
// 维持不变
return sealCode;
});
}