首页 > 解决方案 > 使用 Jackson,我如何序列化参数化方法调用的结果以过滤子对象列表?

问题描述

我正在为我的应用程序框架使用 SpringBoot / Hibernate。我有一个为我的应用程序保存大量参数的类。它有一些始终适用的参数,还有一些根据正在处理的内容而有所不同(每个项目的参数)。这已被建模为包含一组子类集合的父类,其中一个且只有一个子类实例将在任何时候“活跃”,具体取决于某些上下文(例如,正在处理的项目,但真正的case 有一些更复杂的逻辑来确定“活跃”的孩子)。

在几乎所有情况下,我只想序列化当时适用的一个孩子,但在少数情况下,我想序列化整个集合。

我可以使用以下方法实现它:

public class Parent {

    @JsonView(JsonViews.AllChildren.class)
    private Set<Child> children= new HashSet<>();

    @JsonIgnore
    private Context context;

    public void setContext (Context context) {
        this.context = context;
    }

    @JsonView(JsonViews.ActiveChild.class)
    @JsonProperty("activeChild")
    public Child getActiveChild() {

        for (Child child : this.children) {
            if (someFunction(this.context)) {
                return child;
            }
        }

        return null;
    }

然后在我的控制器中我可以这样做:

@GetMapping("/parent")
@JsonView(JsonViews.AllChildren.class)
public Parent getParent() {
    return ParentService.getParent();
}

@GetMapping("/parent/{context}")
@JsonView(JsonViews.ActiveChild.class)
public Parent getParentWithContext(PathVariable final String contextName)) {
    Context context = ContextService.getContextByName(contextName);
    Parent parent = ParentService.getParent();
    parent.setContext(context);
    return Parent;
}

效果很好,但引入了一些我想避免的状态(在父对象上设置上下文)。

所以现在的问题是:如何序列化父/子类以删除状态属性,例如:

@JsonView(JsonViews.ActiveChild.class)
@JsonProperty("activeChild")
public Child getActiveChild(Context context) {

    for (Child child : this.children) {
        if (someFunction(context)) {
            return child;
        }
    }

    return null;
}

@GetMapping("/parent/{context}")
@JsonView(JsonViews.ActiveChild.class)
public Parent getParentWithContext(PathVariable final String contextName)) {
    Context context = ContextService.getContextByName(contextName);
    Parent parent = ParentService.getParent();

    // How to tell the Json serialization to pass the context to getActiveChild

    return Parent;
}

我发现的关于 Json Context 序列化的所有内容似乎都有一组固定的上下文(挖掘一个未知列表),并用于从输出中添加/删除属性,而不是过滤数据。

到目前为止,我发现的唯一解决方案是自己调用 ObjectMapper 以获取所有子级的完整 json 序列化,然后删除除我想要返回的所有子级之外的所有子级。但是这样做意味着我有重复的“哪个孩子在这个上下文中是活动的”逻辑的集合——一个在 Parent 类中与 Parent 和 Child 对象一起工作,另一个在 getParentWithContext 函数中与 json 表示一起工作。有什么更好的我可以做的,例如

  1. 做一些自定义序列化程序,可以在呈现结果之前以某种方式调用父级上的 getActiveChild 方法并传递上下文,或者
  2. 在渲染调用中设置上下文时,以某种方式使上下文成为 ThreadLocal?
  3. 以某种方式创建一个新类,在其构造函数中使用 Context 类实例扩展我的 Parent 类,并将其返回给 Jackson 序列化?
  4. 创建父级的克隆,在克隆上设置上下文,让它被序列化,然后在完成后进行垃圾收集?

标签: javajsonjackson

解决方案


推荐阅读