You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化JSON字符串验证逻辑:冗长重复代码的改进方案与设计模式选择

JSON字段验证逻辑优化问题

现有JSON示例

{
  "productName": "Gold",
  "offerStartDate": "01152023",
  "offerEndDate": "01152024",
  "offerAttributes": [
    {
      "id": "TGH-DAD3KVF3",
      "storeid": "STG-67925",
      "availability": true
    }
  ],
  "offerSpecifications": {
    "price": 23.25
  }
}

当前验证逻辑(Java代码)

Map<String, Object> map = mapper.readValue(json, Map.class);
 
String productNameValue = (String)map.get("productName");
if(productNameValue == null && productNameValue.isEmpty()) {
    throw new Exception();
}
 
String offerStartDateValue = (String)map.get("offerStartDate");
if(offerStartDateValue == null && offerStartDateValue.isEmpty()) {
    throw new Exception();
}
 
List<Object> offerAttributesValue = (List)map.get("offerAttributes");
if(offerAttributesValue == null && offerAttributesValue.isEmpty()) {
    throw new Exception();
}
 
Map<String, Object> offerSpecificationsValue = (Map)map.get("offerSpecifications");
if(offerSpecificationsValue == null && offerSpecificationsValue.isEmpty() && ((String)offerSpecificationsValue.get("price")).isEmpty()) {
    throw new Exception();
}

问题描述

上述仅为JSON响应的部分内容,实际响应包含48个以上字段且结构更复杂,现有代码对所有字段均采用上述重复冗长的方式验证。请问如何优化该验证逻辑?适合采用哪种设计模式?已知Builder模式,但不知如何在此场景应用。


优化方案与设计模式推荐

1. 优先采用验证器模式(Validator Pattern)+ Builder模式

这种组合能让你灵活构建可复用的验证规则,彻底告别重复的if判断代码。

核心思路

  • 定义通用Validator接口,统一验证行为;
  • 为不同类型的字段/结构编写具体验证器(比如字符串非空验证、列表非空验证、嵌套结构验证等);
  • 用Builder模式把这些验证器组装成完整的验证规则链,最后一键执行所有验证。

代码实现示例

首先定义基础Validator接口:

public interface Validator {
    void validate(Map<String, Object> data) throws Exception;
}

然后编写具体验证器实现:

// 验证字符串非空且不为空串
public class NotEmptyStringValidator implements Validator {
    private final String fieldName;

    public NotEmptyStringValidator(String fieldName) {
        this.fieldName = fieldName;
    }

    @Override
    public void validate(Map<String, Object> data) throws Exception {
        String value = (String) data.get(fieldName);
        if (value == null || value.isEmpty()) {
            throw new Exception(String.format("字段'%s'不能为空或空字符串", fieldName));
        }
    }
}

// 验证列表非空且不为空集合
public class NotEmptyListValidator implements Validator {
    private final String fieldName;

    public NotEmptyListValidator(String fieldName) {
        this.fieldName = fieldName;
    }

    @Override
    public void validate(Map<String, Object> data) throws Exception {
        List<Object> value = (List<Object>) data.get(fieldName);
        if (value == null || value.isEmpty()) {
            throw new Exception(String.format("字段'%s'不能为空或空列表", fieldName));
        }
    }
}

// 验证嵌套Map及内部字段
public class NestedMapValidator implements Validator {
    private final String parentField;
    private final List<Validator> nestedValidators;

    public NestedMapValidator(String parentField, List<Validator> nestedValidators) {
        this.parentField = parentField;
        this.nestedValidators = nestedValidators;
    }

    @Override
    public void validate(Map<String, Object> data) throws Exception {
        Map<String, Object> nestedMap = (Map<String, Object>) data.get(parentField);
        if (nestedMap == null || nestedMap.isEmpty()) {
            throw new Exception(String.format("嵌套字段'%s'不能为空或空Map", parentField));
        }
        // 执行嵌套字段的验证
        for (Validator validator : nestedValidators) {
            validator.validate(nestedMap);
        }
    }
}

// 验证数值非空
public class NotNullNumberValidator implements Validator {
    private final String fieldName;

    public NotNullNumberValidator(String fieldName) {
        this.fieldName = fieldName;
    }

    @Override
    public void validate(Map<String, Object> data) throws Exception {
        Number value = (Number) data.get(fieldName);
        if (value == null) {
            throw new Exception(String.format("字段'%s'不能为空", fieldName));
        }
    }
}

接着用Builder模式封装验证规则的组装:

public class ValidationBuilder {
    private final List<Validator> validators = new ArrayList<>();

    public ValidationBuilder addNotEmptyString(String fieldName) {
        validators.add(new NotEmptyStringValidator(fieldName));
        return this;
    }

    public ValidationBuilder addNotEmptyList(String fieldName) {
        validators.add(new NotEmptyListValidator(fieldName));
        return this;
    }

    public ValidationBuilder addNestedMap(String parentField, ValidationBuilder nestedBuilder) {
        validators.add(new NestedMapValidator(parentField, nestedBuilder.validators));
        return this;
    }

    public ValidationBuilder addNotNullNumber(String fieldName) {
        validators.add(new NotNullNumberValidator(fieldName));
        return this;
    }

    public void validate(Map<String, Object> data) throws Exception {
        for (Validator validator : validators) {
            validator.validate(data);
        }
    }
}

最后使用Builder完成验证:

// 构建验证规则链
ValidationBuilder validation = new ValidationBuilder()
        .addNotEmptyString("productName")
        .addNotEmptyString("offerStartDate")
        .addNotEmptyList("offerAttributes")
        .addNestedMap("offerSpecifications",
                new ValidationBuilder().addNotNullNumber("price"));

// 执行验证
Map<String, Object> map = mapper.readValue(json, Map.class);
validation.validate(map);

2. 可选方案:使用注解+反射(结合成熟框架)

如果不想手动实现验证器,也可以用Hibernate Validator这类框架,通过注解快速定义验证规则:

  • 先创建与JSON结构对应的Java实体类,给字段添加@NotNull、@NotEmpty、@Valid(用于嵌套验证)等注解;
  • 直接用框架的Validator验证实体对象,无需手写大量判断逻辑。

示例实体类:

public class Offer {
    @NotNull
    @NotEmpty
    private String productName;

    @NotNull
    @NotEmpty
    private String offerStartDate;

    @NotNull
    @NotEmpty
    private List<OfferAttribute> offerAttributes;

    @NotNull
    @Valid
    private OfferSpecifications offerSpecifications;

    // Getters & Setters
}

public class OfferAttribute {
    @NotNull
    @NotEmpty
    private String id;
    // 其他字段...
}

public class OfferSpecifications {
    @NotNull
    private BigDecimal price;
}

验证代码:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

Offer offer = mapper.readValue(json, Offer.class);
Set<ConstraintViolation<Offer>> violations = validator.validate(offer);
if (!violations.isEmpty()) {
    throw new ConstraintViolationException(violations);
}

这种方式代码量极少,适合复杂结构的验证,唯一的小成本是引入第三方框架依赖。


内容的提问来源于stack exchange,提问作者User27854

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:55:41