Java根据传入的属性字段名称,校验对象(包含父类对象)中的属性字段值是否存在

参考文章

在参考文章的基础上,完善了检查父类字段功能。

/**
 * 对象字段检测工具类
 */
public class ValidationUtil {
    
    private static final String PIX_GET = "get";

    /**
     * 根据传入的属性字段名称,校验bean对象(包含父类字段)中的字段值是否存在
     * @param object 对象
     * @param checkedFields 字段英文列表
     * @param checkedFieldsName 字段中文列表
     * @return
     */
    public static Result checkFieldExistEmpty(Object object, List<String> checkedFields, List<String> checkedFieldsName) {
        if (null == object) {
            throw new ServiceException("ValidationUtil#checkFieldExistEmpty object param is null");
        }

        Class<?> aClass = object.getClass();
        // 获取本类所有的字段
        List<Field> fieldList = new ArrayList(Arrays.asList(aClass.getDeclaredFields()));
        // 合并父类的所有字段
        fieldList.addAll(Arrays.asList(aClass.getSuperclass().getDeclaredFields()));
        String fieldName = "";
        StringBuilder methodName = null;
        Method method = null;
        Object result = null;
        for (Field field : fieldList) {
            fieldName = field.getName();
            if (!hasElement(fieldName, checkedFields)) {
                continue;
            }
            methodName = new StringBuilder(PIX_GET);
            // 驼峰式命名,第一个改为大写,后续保持一致。进行getXxx()操作
            methodName = methodName.append(fieldName.substring(0, 1).toUpperCase())
                    .append(fieldName.substring(1));
            try {
                // 获取本类该字段get方法
                method = aClass.getDeclaredMethod(methodName.toString());
            } catch (NoSuchMethodException e) {
                try {
                    // 获取父类该字段get方法
                    method = aClass.getSuperclass().getDeclaredMethod(methodName.toString());
                } catch (NoSuchMethodException ex) {
                    return Result.failed("未找到该字段信息,请检查数据是否正确。");
                }
            } finally {
                try {
                    result = method.invoke(object);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // 存在空属性
            if (null == result || "".equals(result)) {
                // 获取字段名下标
                int i = checkedFields.indexOf(fieldName);
                // 返回提示消息
                return Result.failed(checkedFieldsName.get(i).concat("不能为空,请完善后重新提交申请。"));
            }
        }

        return Result.succeed("ok");
    }

    /**
     * 检测container数组是否包含element元素
     *
     * @return boolean,true 包含
     */
    private static boolean hasElement(String element, List<String> containers) {
        return containers.contains(element);
    }
}
在Spring AOP(面向切面编程),如果你想要校验接口传递给方法的参数对象(如实体类)的字段是否含有特殊字符,你需要将关注点从单个参数转移到整个对象上。这可以通过创建一个代理类(proxy)来实现,该代理类会对每个字段进行检查。这里有一个简化版的例子: ```java import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; @Aspect public class FieldValidationAspect { @Around("execution(* your.package..*(your.InterfaceType *param))") // 替换为实际接口和类型 public Object validateFieldsBeforeCall(ProceedingJoinPoint joinPoint) throws Throwable { Object param = joinPoint.getArgs()[0]; if (param != null) { // 如果参数非null Class<?> clazz = param.getClass(); BeanInfo beanInfo = Introspector.getBeanInfo(clazz); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor descriptor : propertyDescriptors) { String propertyName = descriptor.getName(); Object fieldValue = Introspector.getBeanPropertyAccessor(param).getPropertyValue(param, propertyName); if (fieldValue instanceof String && !isSafe(fieldValue.toString())) { throw new IllegalArgumentException("参数对象字段 " + propertyName + " 包含了特殊字符"); } } } // 继续执行原方法 return joinPoint.proceed(); } private boolean isSafe(String value) { // 自定义特殊的字符列表或正则表达式 String[] specialChars = {"'", "\"", "<", ">", "|", "{"}; for (String charToCheck : specialChars) { if (value.contains(charToCheck)) { return false; } } return true; } } ``` 这个切面会在调用指定接口方法前遍历参数对象的所有字段,检查其的字符串字段是否包含特殊字符。如果发现有,就抛出异常。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值