如何构造支持AG Grid服务端多条件过滤的动态灵活请求POJO
问题根因
你之前的方案额外定义了PartialFilterModel封装了一层ColumnFilter,但单条件过滤的JSON结构没有外层的columnFilter嵌套字段,直接和ColumnFilter的属性结构一致,导致Jackson字段映射失败。
最优实现方案
核心思路:利用Jackson的字段自动推导类型能力,直接让ColumnFilter(单条件)和新定义的CompleteFilterModel(多条件组合)都作为FilterModel的子类,不需要额外新增类型标识字段,Jackson会根据JSON中存在的字段自动匹配对应的子类。
具体代码修改:
1. FilterModel.java (新增Jackson类型推导注解)
// 根据JSON字段自动匹配子类,无需额外类型字段 @JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION) @JsonSubTypes({ @JsonSubTypes.Type(value = ColumnFilter.class), // 单条件场景 @JsonSubTypes.Type(value = CompleteFilterModel.class) // 多条件组合场景 }) @NoArgsConstructor public abstract class FilterModel implements Serializable { private static final long serialVersionUID = 1L; }
2. ColumnFilter.java (调整父类为FilterModel,其余原有逻辑完全保留)
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "filterType") @JsonSubTypes({ @JsonSubTypes.Type(value = NumberColumnFilter.class, name = "number") }) @Getter @Setter @SuperBuilder @NoArgsConstructor public abstract class ColumnFilter extends FilterModel { // 仅修改继承父类 private static final long serialVersionUID = 1L; String filterType; }
3. 新增CompleteFilterModel.java (多条件组合模型)
@Getter @Setter @SuperBuilder @NoArgsConstructor public class CompleteFilterModel extends FilterModel { private static final long serialVersionUID = 1L; private ColumnFilter condition1; private ColumnFilter condition2; private String operator; // 取值为AND/OR }
4. FilterRequest.java (和你修改后的版本一致,无需改动)
@Getter @Setter public class FilterRequest implements Serializable { private static final long serialVersionUID = 1L; private int startRow; private int endRow; private Map<String, FilterModel> filterModel; private List<SortModel> sortModel; public FilterRequest() { this.filterModel = emptyMap(); this.sortModel = emptyList(); } }
5. NumberColumnFilter.java (完全保留原有代码,无需改动)
业务逻辑使用示例
解析完请求后,直接按类型判断处理即可:
for (FilterModel filter : filterRequest.getFilterModel().values()) { if (filter instanceof ColumnFilter singleCondition) { // 处理单条件过滤,原有逻辑可直接复用 } else if (filter instanceof CompleteFilterModel combineCondition) { String operator = combineCondition.getOperator(); ColumnFilter c1 = combineCondition.getCondition1(); ColumnFilter c2 = combineCondition.getCondition2(); // 按逻辑运算符拼接两个条件即可 } }
方案优势
- 完全兼容新旧两种请求结构,不需要修改前端传参逻辑
- 原有单条件过滤的业务代码几乎零修改复用
- 后续扩展文本、日期等其他类型的过滤规则,仅需给
ColumnFilter新增子类即可,符合开闭原则
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

