报表类系统数据验证设计思路

数据验证设计思路

目录

数据验证设计思路

概述

核心目标

设计原则

1. 分层验证原则

2. 可配置性原则

3. 可扩展性原则

4. 性能优化原则

5. 错误友好原则

验证架构

整体架构图

核心组件

验证类型

1. 基础验证

必填验证

长度验证

格式验证

2. 数据类型验证

数字验证

日期验证

3. 业务验证

唯一性验证

关联验证

4. 自定义验证

技术实现

1. 验证服务核心实现

2. 验证规则引擎

3. 验证器工厂

接口设计

1. REST API 接口

2. 请求响应数据结构

配置管理

1. 数据库表设计

2. 配置文件管理

3. 规则配置管理器

使用示例

1. 前端集成示例

2. Vue.js 集成示例

3. 后端集成示例

最佳实践

1. 验证规则设计原则

分层验证

验证规则优先级

2. 性能优化策略

缓存策略

异步验证

3. 错误处理策略

统一错误响应格式

国际化错误消息

4. 监控和日志

验证性能监控

验证审计日志

扩展方案

1. 插件化验证器

2. 规则引擎集成

3. 机器学习验证

4. 分布式验证

总结

关键设计要点

实施建议


概述

数据验证是确保系统数据质量和业务规则合规性的关键组件。在CRUD表单系统中,数据验证接口负责在数据操作的各个环节对用户输入进行校验,防止无效、不完整或不符合业务规则的数据进入系统。

核心目标

  • 数据完整性:确保必填字段不为空,数据格式正确
  • 业务合规性:验证数据是否符合业务规则和约束
  • 用户体验:提供实时反馈,减少用户重复操作
  • 系统安全性:防止恶意数据注入和系统攻击
  • 维护便利性:提供可配置、可扩展的验证机制

设计原则

1. 分层验证原则

前端验证 → 接口验证 → 业务验证 → 数据库约束
  • 前端验证:提供即时用户反馈,改善用户体验
  • 接口验证:确保API接口的数据安全性
  • 业务验证:执行复杂的业务规则校验
  • 数据库约束:最后一道防线,确保数据完整性

2. 可配置性原则

  • 验证规则通过配置文件或数据库管理
  • 支持动态添加、修改、删除验证规则
  • 无需修改代码即可调整验证逻辑

3. 可扩展性原则

  • 支持自定义验证器
  • 提供插件化的验证机制
  • 易于集成第三方验证组件

4. 性能优化原则

  • 支持验证规则缓存
  • 批量验证优化
  • 异步验证处理

5. 错误友好原则

  • 提供清晰、具体的错误信息
  • 支持多语言错误消息
  • 提供修复建议

验证架构

整体架构图

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   前端验证层     │    │   接口验证层     │    │   业务验证层     │
│                │    │                │    │                │
│ • 实时验证      │    │ • 参数校验      │    │ • 业务规则      │
│ • 格式检查      │────▶│ • 数据类型      │────▶│ • 唯一性检查    │
│ • 用户体验      │    │ • 安全过滤      │    │ • 关联验证      │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                                │
                                ▼
                       ┌─────────────────┐
                       │   数据持久层     │
                       │                │
                       │ • 数据库约束    │
                       │ • 外键检查      │
                       │ • 触发器验证    │
                       └─────────────────┘

核心组件

  1. 验证控制器(ValidationController)
    • 提供统一的验证接口入口
    • 处理验证请求和响应
  2. 验证服务(ValidationService)
    • 核心验证逻辑实现
    • 协调各种验证器的执行
  3. 验证规则引擎(ValidationRuleEngine)
    • 解析和执行验证规则
    • 管理验证规则的生命周期
  4. 验证器工厂(ValidatorFactory)
    • 创建和管理各种验证器实例
    • 支持验证器的注册和发现
  5. 规则配置管理器(RuleConfigManager)
    • 管理验证规则的配置
    • 支持动态加载和更新

验证类型

1. 基础验证

必填验证
@Component
public class RequiredValidator implements FieldValidator {
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        if (value == null || value.toString().trim().isEmpty()) {
            return ValidationResult.error("字段不能为空");
        }
        return ValidationResult.success();
    }
}
长度验证
@Component
public class LengthValidator implements FieldValidator {
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        if (value == null) return ValidationResult.success();
        
        String str = value.toString();
        Integer minLength = rule.getMinLength();
        Integer maxLength = rule.getMaxLength();
        
        if (minLength != null && str.length() < minLength) {
            return ValidationResult.error("长度不能少于" + minLength + "个字符");
        }
        
        if (maxLength != null && str.length() > maxLength) {
            return ValidationResult.error("长度不能超过" + maxLength + "个字符");
        }
        
        return ValidationResult.success();
    }
}
格式验证
@Component
public class PatternValidator implements FieldValidator {
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        if (value == null) return ValidationResult.success();
        
        String pattern = rule.getPattern();
        if (StringUtils.isBlank(pattern)) return ValidationResult.success();
        
        if (!value.toString().matches(pattern)) {
            return ValidationResult.error(rule.getErrorMessage());
        }
        
        return ValidationResult.success();
    }
}

2. 数据类型验证

数字验证
@Component
public class NumberValidator implements FieldValidator {
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        if (value == null) return ValidationResult.success();
        
        try {
            Double.parseDouble(value.toString());
            return ValidationResult.success();
        } catch (NumberFormatException e) {
            return ValidationResult.error("必须是有效的数字");
        }
    }
}
日期验证
@Component
public class DateValidator implements FieldValidator {
    private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
    
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        if (value == null) return ValidationResult.success();
        
        String datePattern = rule.getDatePattern();
        if (StringUtils.isBlank(datePattern)) {
            datePattern = DEFAULT_DATE_PATTERN;
        }
        
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
            sdf.setLenient(false);
            sdf.parse(value.toString());
            return ValidationResult.success();
        } catch (ParseException e) {
            return ValidationResult.error("日期格式不正确,应为:" + datePattern);
        }
    }
}

3. 业务验证

唯一性验证
@Component
public class UniquenessValidator implements BusinessValidator {
    
    @Autowired
    private CrudFormsService crudFormsService;
    
    @Override
    public ValidationResult validate(String uri, String fieldName, Object value, Object recordId) {
        if (value == null) return ValidationResult.success();
        
        // 构建查询条件
        JSONObject params = new JSONObject();
        params.put(fieldName, value);
        
        try {
            List<HashMap<String, Object>> existingRecords = 
                crudFormsService.processSelectDynamicSql(uri, params);
            
            if (!existingRecords.isEmpty()) {
                // 更新操作时排除当前记录
                if (recordId != null) {
                    existingRecords = existingRecords.stream()
                        .filter(record -> !recordId.equals(record.get("id")))
                        .collect(Collectors.toList());
                }
                
                if (!existingRecords.isEmpty()) {
                    return ValidationResult.error(fieldName + "的值已存在,请使用其他值");
                }
            }
            
            return ValidationResult.success();
            
        } catch (Exception e) {
            return ValidationResult.error("唯一性验证失败:" + e.getMessage());
        }
    }
}
关联验证
@Component
public class ReferenceValidator implements BusinessValidator {
    
    @Override
    public ValidationResult validate(String uri, String fieldName, Object value, Map<String, Object> config) {
        if (value == null) return ValidationResult.success();
        
        String referenceTable = (String) config.get("referenceTable");
        String referenceField = (String) config.get("referenceField");
        
        // 验证关联数据是否存在
        // 实现具体的关联验证逻辑
        
        return ValidationResult.success();
    }
}

4. 自定义验证

/**
 * 项目编码验证器示例
 */
@Component("projectCodeValidator")
public class ProjectCodeValidator implements CustomValidator {
    
    @Override
    public ValidationResult validate(Object value, Map<String, Object> context) {
        if (value == null) return ValidationResult.success();
        
        String projectCode = value.toString();
        
        // 项目编码格式:PRJ + 年份 + 4位序号
        String pattern = "^PRJ\\d{4}\\d{4}$";
        if (!projectCode.matches(pattern)) {
            return ValidationResult.error("项目编码格式不正确,应为:PRJ + 年份 + 4位序号");
        }
        
        // 验证年份合理性
        String yearStr = projectCode.substring(3, 7);
        int year = Integer.parseInt(yearStr);
        int currentYear = Calendar.getInstance().get(Calendar.YEAR);
        
        if (year < 2020 || year > currentYear + 1) {
            return ValidationResult.error("项目编码中的年份不合理");
        }
        
        return ValidationResult.success();
    }
}

技术实现

1. 验证服务核心实现

@Service
public class DataValidationServiceImpl implements DataValidationService {
    
    @Autowired
    private ValidationRuleEngine ruleEngine;
    
    @Autowired
    private ValidatorFactory validatorFactory;
    
    @Autowired
    private RuleConfigManager ruleConfigManager;
    
    @Override
    public FieldValidationResult validateField(FieldValidationRequest request) {
        FieldValidationResult result = new FieldValidationResult();
        
        try {
            // 1. 获取验证规则
            List<ValidationRule> rules = ruleConfigManager.getFieldRules(
                request.getUri(), request.getFieldName());
            
            // 2. 执行验证
            for (ValidationRule rule : rules) {
                if (!rule.isEnabled()) continue;
                
                FieldValidator validator = validatorFactory.getValidator(rule.getRuleType());
                ValidationResult validationResult = validator.validate(request.getFieldValue(), rule);
                
                if (!validationResult.isValid()) {
                    result.addError(validationResult.getErrorMessage());
                }
            }
            
            // 3. 业务验证
            if (result.isValid()) {
                executeBusinessValidation(request, result);
            }
            
        } catch (Exception e) {
            result.setValid(false);
            result.addError("验证过程发生异常: " + e.getMessage());
            log.error("字段验证异常", e);
        }
        
        return result;
    }
    
    @Override
    public FormValidationResult validateForm(FormValidationRequest request) {
        FormValidationResult result = new FormValidationResult();
        Map<String, FieldValidationResult> fieldResults = new HashMap<>();
        
        // 1. 逐字段验证
        for (Map.Entry<String, Object> entry : request.getFormData().entrySet()) {
            FieldValidationRequest fieldRequest = new FieldValidationRequest();
            fieldRequest.setUri(request.getUri());
            fieldRequest.setFieldName(entry.getKey());
            fieldRequest.setFieldValue(entry.getValue());
            fieldRequest.setContext(buildContext(request));
            
            FieldValidationResult fieldResult = validateField(fieldRequest);
            fieldResults.put(entry.getKey(), fieldResult);
            
            if (!fieldResult.isValid()) {
                result.setValid(false);
            }
        }
        
        result.setFieldResults(fieldResults);
        
        // 2. 表单级业务验证
        if (result.isValid()) {
            executeFormBusinessValidation(request, result);
        }
        
        return result;
    }
}

2. 验证规则引擎

@Component
public class ValidationRuleEngine {
    
    private final Map<String, FieldValidator> validators = new ConcurrentHashMap<>();
    private final Map<String, BusinessValidator> businessValidators = new ConcurrentHashMap<>();
    
    @PostConstruct
    public void initValidators() {
        // 注册基础验证器
        registerValidator("REQUIRED", new RequiredValidator());
        registerValidator("LENGTH", new LengthValidator());
        registerValidator("PATTERN", new PatternValidator());
        registerValidator("NUMBER", new NumberValidator());
        registerValidator("DATE", new DateValidator());
        registerValidator("EMAIL", new EmailValidator());
        registerValidator("PHONE", new PhoneValidator());
        
        // 注册业务验证器
        registerBusinessValidator("UNIQUENESS", new UniquenessValidator());
        registerBusinessValidator("REFERENCE", new ReferenceValidator());
        registerBusinessValidator("RANGE", new RangeValidator());
    }
    
    public void registerValidator(String type, FieldValidator validator) {
        validators.put(type, validator);
    }
    
    public void registerBusinessValidator(String type, BusinessValidator validator) {
        businessValidators.put(type, validator);
    }
    
    public FieldValidator getValidator(String type) {
        return validators.get(type);
    }
    
    public BusinessValidator getBusinessValidator(String type) {
        return businessValidators.get(type);
    }
}

3. 验证器工厂

@Component
public class ValidatorFactory {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    private final Map<String, FieldValidator> validatorCache = new ConcurrentHashMap<>();
    
    public FieldValidator getValidator(String validatorType) {
        return validatorCache.computeIfAbsent(validatorType, type -> {
            try {
                // 首先尝试从Spring容器获取
                return applicationContext.getBean(type, FieldValidator.class);
            } catch (NoSuchBeanDefinitionException e) {
                // 如果容器中没有,尝试动态创建
                return createValidator(type);
            }
        });
    }
    
    private FieldValidator createValidator(String type) {
        switch (type.toUpperCase()) {
            case "REQUIRED":
                return new RequiredValidator();
            case "LENGTH":
                return new LengthValidator();
            case "PATTERN":
                return new PatternValidator();
            case "NUMBER":
                return new NumberValidator();
            case "DATE":
                return new DateValidator();
            case "EMAIL":
                return new EmailValidator();
            case "PHONE":
                return new PhoneValidator();
            default:
                throw new IllegalArgumentException("未知的验证器类型: " + type);
        }
    }
}

接口设计

1. REST API 接口

@RestController
@RequestMapping("/api/validation")
@Api(tags = "数据验证接口")
public class DataValidationController {
    
    @Autowired
    private DataValidationService validationService;
    
    /**
     * 字段验证接口
     */
    @PostMapping("/field")
    @ApiOperation("字段验证")
    public ResponseResult<FieldValidationResult> validateField(
            @RequestBody @Valid FieldValidationRequest request) {
        
        FieldValidationResult result = validationService.validateField(request);
        return ResponseResult.success(result);
    }
    
    /**
     * 表单验证接口
     */
    @PostMapping("/form")
    @ApiOperation("表单验证")
    public ResponseResult<FormValidationResult> validateForm(
            @RequestBody @Valid FormValidationRequest request) {
        
        FormValidationResult result = validationService.validateForm(request);
        return ResponseResult.success(result);
    }
    
    /**
     * 批量验证接口
     */
    @PostMapping("/batch")
    @ApiOperation("批量验证")
    public ResponseResult<BatchValidationResult> validateBatch(
            @RequestBody @Valid BatchValidationRequest request) {
        
        BatchValidationResult result = validationService.validateBatch(request);
        return ResponseResult.success(result);
    }
    
    /**
     * 获取验证规则接口
     */
    @GetMapping("/rules/{uri}")
    @ApiOperation("获取表单验证规则")
    public ResponseResult<List<ValidationRule>> getValidationRules(
            @PathVariable String uri) {
        
        List<ValidationRule> rules = validationService.getValidationRules(uri);
        return ResponseResult.success(rules);
    }
}

2. 请求响应数据结构

/**
 * 字段验证请求
 */
@Data
@ApiModel("字段验证请求")
public class FieldValidationRequest {
    
    @ApiModelProperty("表单URI")
    @NotBlank(message = "表单URI不能为空")
    private String uri;
    
    @ApiModelProperty("字段名")
    @NotBlank(message = "字段名不能为空")
    private String fieldName;
    
    @ApiModelProperty("字段值")
    private Object fieldValue;
    
    @ApiModelProperty("验证类型")
    private String validationType;
    
    @ApiModelProperty("上下文信息")
    private Map<String, Object> context;
}

/**
 * 字段验证结果
 */
@Data
@ApiModel("字段验证结果")
public class FieldValidationResult {
    
    @ApiModelProperty("是否验证通过")
    private boolean valid = true;
    
    @ApiModelProperty("错误信息列表")
    private List<String> errors;
    
    @ApiModelProperty("警告信息列表")
    private List<String> warnings;
    
    @ApiModelProperty("建议信息")
    private Map<String, Object> suggestions;
    
    public void addError(String error) {
        if (errors == null) errors = new ArrayList<>();
        errors.add(error);
        this.valid = false;
    }
    
    public void addWarning(String warning) {
        if (warnings == null) warnings = new ArrayList<>();
        warnings.add(warning);
    }
}

/**
 * 表单验证请求
 */
@Data
@ApiModel("表单验证请求")
public class FormValidationRequest {
    
    @ApiModelProperty("表单URI")
    @NotBlank(message = "表单URI不能为空")
    private String uri;
    
    @ApiModelProperty("表单数据")
    @NotNull(message = "表单数据不能为空")
    private Map<String, Object> formData;
    
    @ApiModelProperty("操作类型")
    private String operation; // INSERT, UPDATE, DELETE
    
    @ApiModelProperty("记录ID")
    private Object recordId;
    
    @ApiModelProperty("验证组")
    private String validationGroup;
}

/**
 * 表单验证结果
 */
@Data
@ApiModel("表单验证结果")
public class FormValidationResult {
    
    @ApiModelProperty("整体是否验证通过")
    private boolean valid = true;
    
    @ApiModelProperty("各字段验证结果")
    private Map<String, FieldValidationResult> fieldResults;
    
    @ApiModelProperty("全局错误信息")
    private List<String> globalErrors;
    
    @ApiModelProperty("业务规则错误")
    private List<String> businessErrors;
    
    public void addGlobalError(String error) {
        if (globalErrors == null) globalErrors = new ArrayList<>();
        globalErrors.add(error);
        this.valid = false;
    }
    
    public void addBusinessError(String error) {
        if (businessErrors == null) businessErrors = new ArrayList<>();
        businessErrors.add(error);
        this.valid = false;
    }
}

配置管理

1. 数据库表设计

-- 验证规则配置表
CREATE TABLE validation_rules (
    rule_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '规则ID',
    uri VARCHAR(100) NOT NULL COMMENT '表单URI',
    field_name VARCHAR(100) NOT NULL COMMENT '字段名',
    rule_type VARCHAR(50) NOT NULL COMMENT '规则类型',
    rule_expression TEXT COMMENT '规则表达式',
    error_message VARCHAR(500) COMMENT '错误信息',
    is_required TINYINT(1) DEFAULT 0 COMMENT '是否必填',
    min_length INT COMMENT '最小长度',
    max_length INT COMMENT '最大长度',
    min_value DECIMAL(20,6) COMMENT '最小值',
    max_value DECIMAL(20,6) COMMENT '最大值',
    pattern VARCHAR(500) COMMENT '正则表达式',
    allowed_values TEXT COMMENT '允许的值列表(JSON)',
    custom_validator VARCHAR(200) COMMENT '自定义验证器类名',
    validation_group VARCHAR(50) COMMENT '验证组',
    enabled TINYINT(1) DEFAULT 1 COMMENT '是否启用',
    sort_order INT DEFAULT 0 COMMENT '排序',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    INDEX idx_uri_field (uri, field_name),
    INDEX idx_enabled (enabled)
) COMMENT='验证规则配置表';

-- 业务规则配置表
CREATE TABLE business_rules (
    rule_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '规则ID',
    uri VARCHAR(100) NOT NULL COMMENT '表单URI',
    rule_name VARCHAR(100) NOT NULL COMMENT '规则名称',
    rule_type VARCHAR(50) NOT NULL COMMENT '规则类型',
    rule_config TEXT COMMENT '规则配置(JSON)',
    error_message VARCHAR(500) COMMENT '错误信息',
    enabled TINYINT(1) DEFAULT 1 COMMENT '是否启用',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    INDEX idx_uri (uri),
    INDEX idx_enabled (enabled)
) COMMENT='业务规则配置表';

-- 验证规则缓存表
CREATE TABLE validation_rule_cache (
    cache_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '缓存ID',
    cache_key VARCHAR(200) NOT NULL COMMENT '缓存键',
    cache_value TEXT NOT NULL COMMENT '缓存值(JSON)',
    expire_time DATETIME COMMENT '过期时间',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    UNIQUE KEY uk_cache_key (cache_key),
    INDEX idx_expire_time (expire_time)
) COMMENT='验证规则缓存表';

2. 配置文件管理

# application.yml
validation:
  # 验证配置
  config:
    # 是否启用缓存
    cache-enabled: true
    # 缓存过期时间(秒)
    cache-expire-time: 3600
    # 是否启用异步验证
    async-enabled: false
    # 批量验证最大数量
    batch-max-size: 1000
    
  # 默认验证规则
  default-rules:
    # 字符串字段默认最大长度
    string-max-length: 255
    # 数字字段默认精度
    number-precision: 2
    # 日期字段默认格式
    date-format: "yyyy-MM-dd"
    
  # 错误消息配置
  messages:
    required: "{0}不能为空"
    length: "{0}长度必须在{1}-{2}个字符之间"
    pattern: "{0}格式不正确"
    number: "{0}必须是有效的数字"
    date: "{0}日期格式不正确"
    email: "{0}邮箱格式不正确"
    phone: "{0}手机号格式不正确"
    uniqueness: "{0}的值已存在"
    reference: "{0}引用的数据不存在"

3. 规则配置管理器

@Component
public class RuleConfigManager {
    
    @Autowired
    private ValidationRuleMapper validationRuleMapper;
    
    @Autowired
    private BusinessRuleMapper businessRuleMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Value("${validation.config.cache-enabled:true}")
    private boolean cacheEnabled;
    
    @Value("${validation.config.cache-expire-time:3600}")
    private long cacheExpireTime;
    
    /**
     * 获取字段验证规则
     */
    public List<ValidationRule> getFieldRules(String uri, String fieldName) {
        String cacheKey = "validation:field:" + uri + ":" + fieldName;
        
        if (cacheEnabled) {
            List<ValidationRule> cachedRules = getCachedRules(cacheKey);
            if (cachedRules != null) {
                return cachedRules;
            }
        }
        
        List<ValidationRule> rules = validationRuleMapper.selectByUriAndField(uri, fieldName);
        
        if (cacheEnabled && !rules.isEmpty()) {
            cacheRules(cacheKey, rules);
        }
        
        return rules;
    }
    
    /**
     * 获取表单所有验证规则
     */
    public Map<String, List<ValidationRule>> getFormRules(String uri) {
        String cacheKey = "validation:form:" + uri;
        
        if (cacheEnabled) {
            Map<String, List<ValidationRule>> cachedRules = getCachedFormRules(cacheKey);
            if (cachedRules != null) {
                return cachedRules;
            }
        }
        
        List<ValidationRule> allRules = validationRuleMapper.selectByUri(uri);
        Map<String, List<ValidationRule>> formRules = allRules.stream()
            .collect(Collectors.groupingBy(ValidationRule::getFieldName));
        
        if (cacheEnabled && !formRules.isEmpty()) {
            cacheFormRules(cacheKey, formRules);
        }
        
        return formRules;
    }
    
    /**
     * 获取业务规则
     */
    public List<BusinessRule> getBusinessRules(String uri) {
        String cacheKey = "validation:business:" + uri;
        
        if (cacheEnabled) {
            List<BusinessRule> cachedRules = getCachedBusinessRules(cacheKey);
            if (cachedRules != null) {
                return cachedRules;
            }
        }
        
        List<BusinessRule> rules = businessRuleMapper.selectByUri(uri);
        
        if (cacheEnabled && !rules.isEmpty()) {
            cacheBusinessRules(cacheKey, rules);
        }
        
        return rules;
    }
    
    /**
     * 清除缓存
     */
    public void clearCache(String uri) {
        if (!cacheEnabled) return;
        
        Set<String> keys = redisTemplate.keys("validation:*:" + uri + "*");
        if (!keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }
    
    /**
     * 重新加载规则
     */
    public void reloadRules(String uri) {
        clearCache(uri);
        // 预加载规则到缓存
        getFormRules(uri);
        getBusinessRules(uri);
    }
}

使用示例

1. 前端集成示例

// 实时字段验证
class FieldValidator {
    constructor(uri) {
        this.uri = uri;
        this.debounceTime = 300;
    }
    
    // 防抖验证
    validateField = debounce(async (fieldName, fieldValue) => {
        try {
            const response = await fetch('/api/validation/field', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    uri: this.uri,
                    fieldName: fieldName,
                    fieldValue: fieldValue
                })
            });
            
            const result = await response.json();
            this.handleValidationResult(fieldName, result.data);
            
        } catch (error) {
            console.error('验证请求失败:', error);
        }
    }, this.debounceTime);
    
    // 处理验证结果
    handleValidationResult(fieldName, result) {
        const fieldElement = document.querySelector(`[name="${fieldName}"]`);
        const errorElement = document.querySelector(`#${fieldName}-error`);
        
        if (result.valid) {
            fieldElement.classList.remove('error');
            errorElement.textContent = '';
        } else {
            fieldElement.classList.add('error');
            errorElement.textContent = result.errors.join(', ');
        }
    }
    
    // 表单提交验证
    async validateForm(formData) {
        try {
            const response = await fetch('/api/validation/form', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    uri: this.uri,
                    formData: formData,
                    operation: 'INSERT'
                })
            });
            
            const result = await response.json();
            return this.handleFormValidationResult(result.data);
            
        } catch (error) {
            console.error('表单验证失败:', error);
            return false;
        }
    }
    
    // 处理表单验证结果
    handleFormValidationResult(result) {
        if (result.valid) {
            this.clearAllErrors();
            return true;
        }
        
        // 显示字段错误
        if (result.fieldResults) {
            Object.entries(result.fieldResults).forEach(([fieldName, fieldResult]) => {
                if (!fieldResult.valid) {
                    this.showFieldError(fieldName, fieldResult.errors);
                }
            });
        }
        
        // 显示全局错误
        if (result.globalErrors && result.globalErrors.length > 0) {
            this.showGlobalErrors(result.globalErrors);
        }
        
        return false;
    }
}

// 使用示例
const validator = new FieldValidator('userInfo');

// 绑定字段验证事件
document.querySelectorAll('input, select, textarea').forEach(element => {
    element.addEventListener('blur', (event) => {
        validator.validateField(event.target.name, event.target.value);
    });
});

// 表单提交验证
document.getElementById('submitBtn').addEventListener('click', async (event) => {
    event.preventDefault();
    
    const formData = new FormData(document.getElementById('userForm'));
    const data = Object.fromEntries(formData.entries());
    
    const isValid = await validator.validateForm(data);
    if (isValid) {
        // 提交表单数据
        submitFormData(data);
    }
});

2. Vue.js 集成示例

<template>
  <el-form ref="formRef" :model="formData" :rules="validationRules">
    <el-form-item label="用户名" prop="username">
      <el-input 
        v-model="formData.username" 
        @blur="validateField('username')"
        :class="{ 'error': fieldErrors.username }"
      />
      <div v-if="fieldErrors.username" class="error-message">
        {{ fieldErrors.username }}
      </div>
    </el-form-item>
    
    <el-form-item label="邮箱" prop="email">
      <el-input 
        v-model="formData.email" 
        @blur="validateField('email')"
        :class="{ 'error': fieldErrors.email }"
      />
      <div v-if="fieldErrors.email" class="error-message">
        {{ fieldErrors.email }}
      </div>
    </el-form-item>
    
    <el-form-item>
      <el-button type="primary" @click="submitForm">提交</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
import { debounce } from 'lodash';

export default {
  name: 'UserForm',
  data() {
    return {
      uri: 'userInfo',
      formData: {
        username: '',
        email: ''
      },
      fieldErrors: {},
      validationRules: {}
    };
  },
  
  mounted() {
    this.loadValidationRules();
  },
  
  methods: {
    // 加载验证规则
    async loadValidationRules() {
      try {
        const response = await this.$http.get(`/api/validation/rules/${this.uri}`);
        this.buildElementUIRules(response.data);
      } catch (error) {
        console.error('加载验证规则失败:', error);
      }
    },
    
    // 构建Element UI验证规则
    buildElementUIRules(rules) {
      const elementRules = {};
      
      rules.forEach(rule => {
        if (!elementRules[rule.fieldName]) {
          elementRules[rule.fieldName] = [];
        }
        
        const elementRule = {
          message: rule.errorMessage,
          trigger: 'blur'
        };
        
        switch (rule.ruleType) {
          case 'REQUIRED':
            elementRule.required = true;
            break;
          case 'LENGTH':
            elementRule.min = rule.minLength;
            elementRule.max = rule.maxLength;
            break;
          case 'PATTERN':
            elementRule.pattern = new RegExp(rule.pattern);
            break;
        }
        
        elementRules[rule.fieldName].push(elementRule);
      });
      
      this.validationRules = elementRules;
    },
    
    // 字段验证(防抖)
    validateField: debounce(async function(fieldName) {
      try {
        const response = await this.$http.post('/api/validation/field', {
          uri: this.uri,
          fieldName: fieldName,
          fieldValue: this.formData[fieldName]
        });
        
        const result = response.data;
        if (result.valid) {
          this.$delete(this.fieldErrors, fieldName);
        } else {
          this.$set(this.fieldErrors, fieldName, result.errors.join(', '));
        }
        
      } catch (error) {
        console.error('字段验证失败:', error);
      }
    }, 300),
    
    // 表单提交
    async submitForm() {
      try {
        // 先进行Element UI验证
        const valid = await this.$refs.formRef.validate();
        if (!valid) return;
        
        // 再进行服务端验证
        const response = await this.$http.post('/api/validation/form', {
          uri: this.uri,
          formData: this.formData,
          operation: 'INSERT'
        });
        
        const result = response.data;
        if (result.valid) {
          // 提交数据
          await this.submitData();
          this.$message.success('提交成功');
        } else {
          this.handleValidationErrors(result);
        }
        
      } catch (error) {
        console.error('表单提交失败:', error);
        this.$message.error('提交失败');
      }
    },
    
    // 处理验证错误
    handleValidationErrors(result) {
      // 清除之前的错误
      this.fieldErrors = {};
      
      // 显示字段错误
      if (result.fieldResults) {
        Object.entries(result.fieldResults).forEach(([fieldName, fieldResult]) => {
          if (!fieldResult.valid) {
            this.$set(this.fieldErrors, fieldName, fieldResult.errors.join(', '));
          }
        });
      }
      
      // 显示全局错误
      if (result.globalErrors && result.globalErrors.length > 0) {
        this.$message.error(result.globalErrors.join(', '));
      }
    },
    
    // 提交数据
    async submitData() {
      const response = await this.$http.post(`/api/dataManager/insert/${this.uri}`, this.formData);
      return response.data;
    }
  }
};
</script>

<style scoped>
.error {
  border-color: #f56c6c !important;
}

.error-message {
  color: #f56c6c;
  font-size: 12px;
  margin-top: 4px;
}
</style>

3. 后端集成示例

/**
 * 在现有CRUD控制器中集成验证
 */
@RestController
@RequestMapping("/api")
public class CurdFormsController {
    
    @Autowired
    private DataValidationService validationService;
    
    @Autowired
    private CrudFormsService crudFormsService;
    
    /**
     * 插入数据(集成验证)
     */
    @PostMapping("/dataManager/insert/{uri}")
    public ResponseResult<Boolean> processInsertDynamicSql(
            @PathVariable String uri, 
            @RequestBody JSONObject params) {
        
        // 1. 数据验证
        FormValidationRequest validationRequest = new FormValidationRequest();
        validationRequest.setUri(uri);
        validationRequest.setFormData(params);
        validationRequest.setOperation("INSERT");
        
        FormValidationResult validationResult = validationService.validateForm(validationRequest);
        
        // 2. 验证失败时返回详细错误信息
        if (!validationResult.isValid()) {
            return ResponseResult.fail(1010, "数据验证失败", validationResult);
        }
        
        // 3. 验证通过后执行插入
        try {
            int result = crudFormsService.processInsertDynamicSql(uri, params);
            return ResponseResult.success(result > 0);
        } catch (Exception e) {
            log.error("数据插入失败", e);
            return ResponseResult.fail(1001, "数据插入失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新数据(集成验证)
     */
    @PostMapping("/dataManager/update/{uri}")
    public ResponseResult<Boolean> processUpdateDynamicSql(
            @PathVariable String uri, 
            @RequestBody JSONObject params) {
        
        // 1. 数据验证
        FormValidationRequest validationRequest = new FormValidationRequest();
        validationRequest.setUri(uri);
        validationRequest.setFormData(params);
        validationRequest.setOperation("UPDATE");
        validationRequest.setRecordId(params.get("id")); // 假设主键字段为id
        
        FormValidationResult validationResult = validationService.validateForm(validationRequest);
        
        // 2. 验证失败时返回详细错误信息
        if (!validationResult.isValid()) {
            return ResponseResult.fail(1010, "数据验证失败", validationResult);
        }
        
        // 3. 验证通过后执行更新
        try {
            int result = crudFormsService.processUpdateDynamicSql(uri, params);
            return ResponseResult.success(result > 0);
        } catch (Exception e) {
            log.error("数据更新失败", e);
            return ResponseResult.fail(1002, "数据更新失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量操作验证
     */
    @PostMapping("/dataManager/batch-insert/{uri}")
    public ResponseResult<BatchOperationResult> processBatchInsert(
            @PathVariable String uri,
            @RequestBody List<JSONObject> dataList) {
        
        // 1. 批量验证
        BatchValidationRequest validationRequest = new BatchValidationRequest();
        validationRequest.setUri(uri);
        validationRequest.setDataList(dataList);
        validationRequest.setOperation("INSERT");
        
        BatchValidationResult validationResult = validationService.validateBatch(validationRequest);
        
        // 2. 处理验证结果
        BatchOperationResult operationResult = new BatchOperationResult();
        
        if (validationResult.hasErrors()) {
            // 有验证错误,返回错误详情
            operationResult.setSuccess(false);
            operationResult.setValidationErrors(validationResult.getErrors());
            return ResponseResult.fail(1010, "批量数据验证失败", operationResult);
        }
        
        // 3. 验证通过,执行批量插入
        try {
            List<Integer> results = new ArrayList<>();
            for (JSONObject data : dataList) {
                int result = crudFormsService.processInsertDynamicSql(uri, data);
                results.add(result);
            }
            
            operationResult.setSuccess(true);
            operationResult.setResults(results);
            operationResult.setTotalCount(dataList.size());
            operationResult.setSuccessCount(results.size());
            
            return ResponseResult.success(operationResult);
            
        } catch (Exception e) {
            log.error("批量插入失败", e);
            operationResult.setSuccess(false);
            operationResult.setErrorMessage("批量插入失败: " + e.getMessage());
            return ResponseResult.fail(1003, "批量插入失败", operationResult);
        }
    }
}

最佳实践

1. 验证规则设计原则

分层验证
前端验证(用户体验)
    ↓
接口验证(数据安全)
    ↓
业务验证(业务规则)
    ↓
数据库约束(数据完整性)
验证规则优先级
  1. 必填验证 - 最高优先级
  2. 格式验证 - 数据类型和格式
  3. 长度验证 - 字符串长度限制
  4. 范围验证 - 数值范围限制
  5. 业务验证 - 唯一性、关联性等
  6. 自定义验证 - 复杂业务逻辑

2. 性能优化策略

缓存策略
@Service
public class ValidationCacheService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private static final String CACHE_PREFIX = "validation:";
    private static final long DEFAULT_EXPIRE_TIME = 3600; // 1小时
    
    /**
     * 缓存验证规则
     */
    public void cacheValidationRules(String uri, List<ValidationRule> rules) {
        String cacheKey = CACHE_PREFIX + "rules:" + uri;
        redisTemplate.opsForValue().set(cacheKey, rules, DEFAULT_EXPIRE_TIME, TimeUnit.SECONDS);
    }
    
    /**
     * 获取缓存的验证规则
     */
    @SuppressWarnings("unchecked")
    public List<ValidationRule> getCachedValidationRules(String uri) {
        String cacheKey = CACHE_PREFIX + "rules:" + uri;
        return (List<ValidationRule>) redisTemplate.opsForValue().get(cacheKey);
    }
    
    /**
     * 缓存验证结果(短期缓存)
     */
    public void cacheValidationResult(String key, ValidationResult result) {
        String cacheKey = CACHE_PREFIX + "result:" + key;
        redisTemplate.opsForValue().set(cacheKey, result, 300, TimeUnit.SECONDS); // 5分钟
    }
}
异步验证
@Service
public class AsyncValidationService {
    
    @Autowired
    private TaskExecutor taskExecutor;
    
    /**
     * 异步字段验证
     */
    public CompletableFuture<FieldValidationResult> validateFieldAsync(FieldValidationRequest request) {
        return CompletableFuture.supplyAsync(() -> {
            return validationService.validateField(request);
        }, taskExecutor);
    }
    
    /**
     * 异步批量验证
     */
    public CompletableFuture<BatchValidationResult> validateBatchAsync(BatchValidationRequest request) {
        return CompletableFuture.supplyAsync(() -> {
            return validationService.validateBatch(request);
        }, taskExecutor);
    }
}

3. 错误处理策略

统一错误响应格式
@Data
public class ValidationError {
    private String field;           // 字段名
    private String code;            // 错误代码
    private String message;         // 错误信息
    private Object rejectedValue;   // 被拒绝的值
    private Map<String, Object> context; // 上下文信息
}

@Data
public class ValidationResponse {
    private boolean success;
    private List<ValidationError> errors;
    private Map<String, Object> metadata;
    
    public static ValidationResponse success() {
        ValidationResponse response = new ValidationResponse();
        response.setSuccess(true);
        return response;
    }
    
    public static ValidationResponse fail(List<ValidationError> errors) {
        ValidationResponse response = new ValidationResponse();
        response.setSuccess(false);
        response.setErrors(errors);
        return response;
    }
}
国际化错误消息
@Component
public class ValidationMessageResolver {
    
    @Autowired
    private MessageSource messageSource;
    
    public String resolveMessage(String code, Object[] args, Locale locale) {
        try {
            return messageSource.getMessage(code, args, locale);
        } catch (NoSuchMessageException e) {
            return code; // 返回错误代码作为默认消息
        }
    }
    
    public String resolveFieldMessage(String fieldName, String ruleType, Object[] args, Locale locale) {
        String code = "validation." + ruleType.toLowerCase();
        Object[] messageArgs = new Object[args.length + 1];
        messageArgs[0] = fieldName;
        System.arraycopy(args, 0, messageArgs, 1, args.length);
        
        return resolveMessage(code, messageArgs, locale);
    }
}

4. 监控和日志

验证性能监控
@Component
@Slf4j
public class ValidationMonitor {
    
    private final MeterRegistry meterRegistry;
    private final Timer validationTimer;
    private final Counter validationCounter;
    
    public ValidationMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.validationTimer = Timer.builder("validation.duration")
            .description("Validation execution time")
            .register(meterRegistry);
        this.validationCounter = Counter.builder("validation.count")
            .description("Validation execution count")
            .register(meterRegistry);
    }
    
    public <T> T monitorValidation(String operation, Supplier<T> validationSupplier) {
        Timer.Sample sample = Timer.start(meterRegistry);
        try {
            T result = validationSupplier.get();
            validationCounter.increment(Tags.of("operation", operation, "result", "success"));
            return result;
        } catch (Exception e) {
            validationCounter.increment(Tags.of("operation", operation, "result", "error"));
            throw e;
        } finally {
            sample.stop(validationTimer.withTags("operation", operation));
        }
    }
}
验证审计日志
@Component
@Slf4j
public class ValidationAuditLogger {
    
    public void logValidationAttempt(String uri, String operation, String userId, Map<String, Object> data) {
        log.info("Validation attempt - URI: {}, Operation: {}, User: {}, Data: {}", 
            uri, operation, userId, maskSensitiveData(data));
    }
    
    public void logValidationResult(String uri, String operation, String userId, boolean success, List<String> errors) {
        if (success) {
            log.info("Validation success - URI: {}, Operation: {}, User: {}", uri, operation, userId);
        } else {
            log.warn("Validation failed - URI: {}, Operation: {}, User: {}, Errors: {}", 
                uri, operation, userId, errors);
        }
    }
    
    public void logValidationError(String uri, String operation, String userId, Exception error) {
        log.error("Validation error - URI: {}, Operation: {}, User: {}, Error: {}", 
            uri, operation, userId, error.getMessage(), error);
    }
    
    private Map<String, Object> maskSensitiveData(Map<String, Object> data) {
        // 实现敏感数据脱敏逻辑
        Map<String, Object> maskedData = new HashMap<>(data);
        maskedData.replaceAll((key, value) -> {
            if (isSensitiveField(key)) {
                return "***";
            }
            return value;
        });
        return maskedData;
    }
    
    private boolean isSensitiveField(String fieldName) {
        return fieldName.toLowerCase().contains("password") 
            || fieldName.toLowerCase().contains("secret")
            || fieldName.toLowerCase().contains("token");
    }
}

扩展方案

1. 插件化验证器

/**
 * 验证器插件接口
 */
public interface ValidationPlugin {
    
    /**
     * 插件名称
     */
    String getName();
    
    /**
     * 插件版本
     */
    String getVersion();
    
    /**
     * 支持的验证类型
     */
    List<String> getSupportedTypes();
    
    /**
     * 创建验证器
     */
    FieldValidator createValidator(String type, Map<String, Object> config);
    
    /**
     * 插件初始化
     */
    void initialize(ValidationContext context);
    
    /**
     * 插件销毁
     */
    void destroy();
}

/**
 * 插件管理器
 */
@Component
public class ValidationPluginManager {
    
    private final Map<String, ValidationPlugin> plugins = new ConcurrentHashMap<>();
    private final Map<String, FieldValidator> validators = new ConcurrentHashMap<>();
    
    /**
     * 注册插件
     */
    public void registerPlugin(ValidationPlugin plugin) {
        plugins.put(plugin.getName(), plugin);
        
        // 注册插件支持的验证器
        for (String type : plugin.getSupportedTypes()) {
            validators.put(type, plugin.createValidator(type, Collections.emptyMap()));
        }
        
        log.info("Registered validation plugin: {} v{}", plugin.getName(), plugin.getVersion());
    }
    
    /**
     * 获取验证器
     */
    public FieldValidator getValidator(String type) {
        return validators.get(type);
    }
    
    /**
     * 动态加载插件
     */
    public void loadPlugin(String pluginPath) {
        try {
            // 实现动态类加载逻辑
            URLClassLoader classLoader = new URLClassLoader(new URL[]{new File(pluginPath).toURI().toURL()});
            // 加载插件类并注册
        } catch (Exception e) {
            log.error("Failed to load validation plugin: {}", pluginPath, e);
        }
    }
}

2. 规则引擎集成

/**
 * 规则引擎验证器
 */
@Component
public class RuleEngineValidator implements FieldValidator {
    
    @Autowired
    private DroolsRuleEngine ruleEngine;
    
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        try {
            // 构建规则执行上下文
            RuleContext context = new RuleContext();
            context.setFieldName(rule.getFieldName());
            context.setFieldValue(value);
            context.setRuleExpression(rule.getRuleExpression());
            
            // 执行规则
            RuleResult result = ruleEngine.execute(context);
            
            if (result.isValid()) {
                return ValidationResult.success();
            } else {
                return ValidationResult.error(result.getErrorMessage());
            }
            
        } catch (Exception e) {
            log.error("Rule engine validation failed", e);
            return ValidationResult.error("规则执行失败: " + e.getMessage());
        }
    }
}

/**
 * Drools规则引擎实现
 */
@Component
public class DroolsRuleEngine {
    
    private KieContainer kieContainer;
    
    @PostConstruct
    public void initialize() {
        KieServices kieServices = KieServices.Factory.get();
        kieContainer = kieServices.getKieClasspathContainer();
    }
    
    public RuleResult execute(RuleContext context) {
        KieSession kieSession = kieContainer.newKieSession();
        
        try {
            // 插入事实
            kieSession.insert(context);
            
            // 执行规则
            kieSession.fireAllRules();
            
            // 获取结果
            return context.getResult();
            
        } finally {
            kieSession.dispose();
        }
    }
}

3. 机器学习验证

/**
 * 机器学习验证器
 */
@Component
public class MLValidator implements FieldValidator {
    
    @Autowired
    private MLModelService mlModelService;
    
    @Override
    public ValidationResult validate(Object value, ValidationRule rule) {
        try {
            String modelName = rule.getCustomValidator();
            if (StringUtils.isBlank(modelName)) {
                return ValidationResult.success();
            }
            
            // 准备特征数据
            Map<String, Object> features = prepareFeatures(value, rule);
            
            // 调用ML模型进行预测
            MLPredictionResult prediction = mlModelService.predict(modelName, features);
            
            if (prediction.isValid()) {
                return ValidationResult.success();
            } else {
                return ValidationResult.error("数据异常,置信度: " + prediction.getConfidence());
            }
            
        } catch (Exception e) {
            log.error("ML validation failed", e);
            return ValidationResult.success(); // ML验证失败时不阻止业务流程
        }
    }
    
    private Map<String, Object> prepareFeatures(Object value, ValidationRule rule) {
        Map<String, Object> features = new HashMap<>();
        features.put("value", value);
        features.put("fieldName", rule.getFieldName());
        features.put("dataType", value != null ? value.getClass().getSimpleName() : "null");
        // 添加更多特征...
        return features;
    }
}

4. 分布式验证

/**
 * 分布式验证服务
 */
@Service
public class DistributedValidationService {
    
    @Autowired
    private ValidationClusterManager clusterManager;
    
    @Autowired
    private LoadBalancer loadBalancer;
    
    /**
     * 分布式表单验证
     */
    public CompletableFuture<FormValidationResult> validateFormDistributed(FormValidationRequest request) {
        // 将表单字段分组,分配到不同的验证节点
        Map<String, List<String>> fieldGroups = groupFields(request.getFormData().keySet());
        
        List<CompletableFuture<Map<String, FieldValidationResult>>> futures = new ArrayList<>();
        
        for (Map.Entry<String, List<String>> entry : fieldGroups.entrySet()) {
            String nodeId = entry.getKey();
            List<String> fields = entry.getValue();
            
            CompletableFuture<Map<String, FieldValidationResult>> future = 
                validateFieldsOnNode(nodeId, request, fields);
            futures.add(future);
        }
        
        // 等待所有验证完成并合并结果
        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
            .thenApply(v -> {
                FormValidationResult result = new FormValidationResult();
                Map<String, FieldValidationResult> allFieldResults = new HashMap<>();
                
                for (CompletableFuture<Map<String, FieldValidationResult>> future : futures) {
                    try {
                        allFieldResults.putAll(future.get());
                    } catch (Exception e) {
                        log.error("Failed to get validation result", e);
                    }
                }
                
                result.setFieldResults(allFieldResults);
                result.setValid(allFieldResults.values().stream().allMatch(FieldValidationResult::isValid));
                
                return result;
            });
    }
    
    private Map<String, List<String>> groupFields(Set<String> fields) {
        // 实现字段分组逻辑,将字段分配到不同的验证节点
        Map<String, List<String>> groups = new HashMap<>();
        List<String> availableNodes = clusterManager.getAvailableNodes();
        
        int nodeIndex = 0;
        for (String field : fields) {
            String nodeId = availableNodes.get(nodeIndex % availableNodes.size());
            groups.computeIfAbsent(nodeId, k -> new ArrayList<>()).add(field);
            nodeIndex++;
        }
        
        return groups;
    }
    
    private CompletableFuture<Map<String, FieldValidationResult>> validateFieldsOnNode(
            String nodeId, FormValidationRequest request, List<String> fields) {
        
        return CompletableFuture.supplyAsync(() -> {
            try {
                // 调用远程验证服务
                ValidationServiceClient client = clusterManager.getClient(nodeId);
                
                Map<String, Object> fieldData = new HashMap<>();
                for (String field : fields) {
                    fieldData.put(field, request.getFormData().get(field));
                }
                
                PartialFormValidationRequest partialRequest = new PartialFormValidationRequest();
                partialRequest.setUri(request.getUri());
                partialRequest.setFieldData(fieldData);
                partialRequest.setOperation(request.getOperation());
                
                return client.validateFields(partialRequest);
                
            } catch (Exception e) {
                log.error("Failed to validate fields on node: {}", nodeId, e);
                // 返回失败结果
                Map<String, FieldValidationResult> errorResults = new HashMap<>();
                for (String field : fields) {
                    FieldValidationResult errorResult = new FieldValidationResult();
                    errorResult.setValid(false);
                    errorResult.addError("验证服务不可用");
                    errorResults.put(field, errorResult);
                }
                return errorResults;
            }
        });
    }
}

总结

数据验证设计思路的核心在于构建一个分层、可配置、可扩展的验证体系,确保数据质量和业务规则的合规性。

关键设计要点

  1. 分层验证架构
    • 前端验证提升用户体验
    • 接口验证确保数据安全
    • 业务验证保证规则合规
    • 数据库约束作为最后防线
  2. 可配置化管理
    • 验证规则通过数据库配置
    • 支持动态加载和更新
    • 提供可视化配置界面
  3. 高性能设计
    • 验证规则缓存机制
    • 异步验证处理
    • 批量验证优化
  4. 扩展性支持
    • 插件化验证器架构
    • 自定义验证器接口
    • 规则引擎集成能力
  5. 用户友好性
    • 实时验证反馈
    • 清晰的错误信息
    • 多语言支持

实施建议

  1. 分阶段实施
    • 第一阶段:基础验证功能
    • 第二阶段:业务规则验证
    • 第三阶段:高级特性和优化
  2. 性能监控
    • 建立验证性能指标
    • 监控验证成功率
    • 优化验证响应时间
  3. 持续改进
    • 收集用户反馈
    • 优化验证规则
    • 扩展验证能力

通过这套完整的数据验证设计方案,可以显著提升系统的数据质量、用户体验和业务规则的执行效果,为CRUD表单系统提供强有力的数据保障。


文档版本: 1.0

创建时间

适用项目: CRUD表单系统

维护人: 开发团队

按需引入<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ant Design Vue 纯HTML项目示例</title> <!-- 引入Ant Design Vue的CSS --> <link rel="stylesheet" href="https://unpkg.com/ant-design-vue@3.2.21/dist/antd.css"> <!-- 引入Ant Design X Vue的CSS --> <link rel="stylesheet" href="https://unpkg.com/ant-design-x-vue@1.0.0/dist/antdx.css"> <!-- vue3引入 --> <script src="https://unpkg.com/dayjs/dayjs.min.js"></script> <script src="https://unpkg.com/dayjs/plugin/customParseFormat.js"></script> <script src="https://unpkg.com/dayjs/plugin/weekday.js"></script> <script src="https://unpkg.com/dayjs/plugin/localeData.js"></script> <script src="https://unpkg.com/dayjs/plugin/weekOfYear.js"></script> <script src="https://unpkg.com/dayjs/plugin/weekYear.js"></script> <script src="https://unpkg.com/dayjs/plugin/advancedFormat.js"></script> <script src="https://unpkg.com/dayjs/plugin/quarterOfYear.js"></script> <!-- vue3 --> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <!-- antdv --> <script src="https://cdn.jsdelivr.net/npm/ant-design-vue@4.2.6/dist/antd.min.js"></script> <!-- antdxv --> <script src="https://cdn.jsdelivr.net/npm/ant-design-x-vue@1.2.7/dist/index.umd.min.js"></script> </head> <body> <div id="app"></div> <script> const { createApp, ref, computed } = Vue; const { Button } = antd; const { Bubble, XProvider } = antdx; createApp({ template: ` <AXProvider :theme="{ algorithm: myThemeAlgorithm, }"> <div :style="{ padding: &#39;24px&#39;, backgroundColor: bgColor, }"> UMD <AXBubble content="hello bubble"></AXBubble> <AButton type="primary" @click="setLightTheme">Light</AButton> <AButton type="primary" @click="setDarkTheme">Dark</AButton> </div> </AXProvider> `, setup() { const { theme } = antd; const bgColor = ref("white"); const myThemeAlgorithm = ref(theme.defaultAlgorithm); const setLightTheme = () => { myThemeAlgorithm.value = theme.defaultAlgorithm; bgColor.value = "white"; }; const setDarkTheme = () => { myThemeAlgorithm.value = theme.darkAlgorithm; bgColor.value = "#141414"; }; return { myThemeAlgorithm, bgColor, setLightTheme, setDarkTheme }; } }) .use(XProvider) .use(Button) .use(Bubble) .mount("#app"); </script> <style> .container { max-width: 1200px; margin: 24px auto; padding: 0 16px; } .search-form { margin-bottom: 24px; padding: 16px; background-color: #f5f5f5; border-radius: 4px; } .user-table { margin-top: 16px; } .mb-6 { margin-bottom: 24px; } .mt-2 { margin-top: 8px; } </style> </body> </html>
07-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值