1.注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Trim {
}
2.注解解析器
@Slf4j
public class TrimResolver implements FieldResolver {/**
* 遍历传入对象的属性(Field),
* <p>
* 如果持有 {@link Trim @Trim} 注解,修剪字符串开头和结尾的空白。
* <p>
* 如果持有 {@link Trim @Trim} 注解的属性的值不是String类型,则递归遍历该属性引用的对象。
*
* @param obj
* @see String#trim()
*/
public void trim(Object obj) {
try {
this.resolve(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}@Override
public void doResolve(Object obj) throws Exception {
this.resolveFields(obj);
}@Override
public void resolveField(Object obj, Field field) throws InvocationTargetException, IllegalAccessException {
Class<?> clazz = obj.getClass();
Trim trimAnnotation = field.getAnnotation(Trim.class);
if (trimAnnotation == null) {
return;
}
// 获取持有 @Trim 注解的字段的值
Object fieldValue = BeanUtil.readField(obj, field,
() -> log.warn("持有@Trim注解的字段[{}#{}]缺少Getter方法", clazz.getName(), field.getName()));
// 如果持有 @Trim 注解的字段的值不是 String 类型,则递归遍历该字段引用的对象。
if (!(fieldValue instanceof String)) {
this.trim(fieldValue);
return;
}
// 修剪字符串开头和结尾的空白
String trimValue = this.trim((String) fieldValue);
// 给持有 @Trim 注解的字段赋值
BeanUtil.writeField(obj, field, trimValue,
() -> log.warn("持有@Trim注解的字段[{}#{}]缺少Setter方法", clazz.getName(), field.getName()));
}@Override
@SuppressWarnings("unchecked")
public void resolveCollection(Collection collection) throws Exception {
Object[] array = collection.toArray();
this.resolveArray(array);
collection.clear();
collection.addAll(Arrays.asList(array));
}@Override
public void resolveArray(Object array) throws Exception {
int length = Array.getLength(array);
for (int i = 0; i < length; i++) {
Object item = Array.get(array, i);
if (item instanceof String) {
Array.set(array, i, this.trim((String) item));
continue;
}
this.resolve(item);
}
}private String trim(String s) {
if (s == null) {
return null;
}
return s.trim();
}}