【问题标题】:How to change JsonView for specific properties如何更改特定属性的 JsonView
【发布时间】:2016-01-22 10:10:28
【问题描述】:

您好,我很少有相互嵌入的 UI 对象。示例 #1:

class CarUI {
  public UserUI user;
  public UserUI agent;
  ....
  public UserUI getUser() {
    return user;
  }
  public UserUI getAgent() {
    return agent;
  }
}
class UserUI {
  @JsonView({Views.Public.class,Views.Private.class})
  public String name;
  @JsonView({Views.Private.class})
  public String phone;
  ...
}

如您所见,如果我将 UserUI 序列化为 Public,我将只公开名称,但对于私有,我将公开所有字段。

这是我的问题:当我序列化对象 CarUI 时,我只想公开“用户”的名称和“代理”的名称+电话。这实质上意味着在 getUser() 的 getter 中,我想将 JsonView 更改为 Views.Public.class,而对于 getAgent(),我想将其更改为 Views.Private.class

有没有办法覆盖 getter 中的 JsonView 以使返回对象的所有层次结构现在都使用这个新的 JsonView 序列化?

已编辑 如下所述,您可以使用 JsonView 继承解决我的 Example#1。更通用的呢。这是示例#2:

class CarUI {
  public UserUI user;
  public UserUI agent;
  ....
  public UserUI getUser() {
    return user;
  }
  public UserUI getAgent() {
    return agent;
  }
}
class UserUI {
  @JsonView({Views.Public.class,Views.Private.class})
  public String name;
  @JsonView({Views.Private.class})
  public String phone;
  @JsonView({Views.Public.class})
  public String avatarUrl;
  ...
}

在此示例中,我希望为代理显示姓名+电话,为用户显示姓名+头像Url。

【问题讨论】:

    标签: java serialization jackson json-view


    【解决方案1】:

    @JsonView 接受继承。 Views.Private 字段扩展 Views.Public 字段。这意味着 Views.Private 序列化也将查找 Views.Public 注释。

    public Views {
        public Public {}
        public Private extends Public {}
    }
    
    class CarUI {
      public UserUI user;
      public UserUI agent;
      ....
      @JsonView(Views.Public.class)
      public UserUI getUser() {
        return user;
      }
      @JsonView(Views.Private.class)
      public UserUI getAgent() {
        return agent;
      }
    }
    
    class UserUI {
      @JsonView(Views.Public.class)
      public String name;
      @JsonView(Views.Private.class)
      public String phone;
      ...
    }
    

    例如#2

    您可以引入多个类,例如:

    public Views {
        public Public {}
        public Private1 extends Public {}
        public Private2 extends Public {}
    }
    
    class CarUI {
      public UserUI user;
      public UserUI agent;
      ....
      public UserUI getUser() {
        return user;
      }
      public UserUI getAgent() {
        return agent;
      }
    }
    class UserUI {
      @JsonView(Views.Public.class)
      public String name;
      @JsonView({Views.Private1.class})
      public String phone;
      @JsonView({Views.Private2.class})
      public String avatarUrl;
      ...
    }
    

    或者您可以使用无视图属性而不使用继承:

    public Views {
        public Public {}
        public Private {}
    }
    
    class CarUI {
      public UserUI user;
      public UserUI agent;
      ....
      public UserUI getUser() {
        return user;
      }
      public UserUI getAgent() {
        return agent;
      }
    }
    class UserUI {
      // This one is view-less shows every time unless you specificy
      public String name;
      @JsonView({Views.Private.class})
      public String phone;
      @JsonView({Views.Public.class})
      public String avatarUrl;
      ...
    }
    
    ...
    // If you want to hide view-less properties, default is true 
    objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false); 
    ...
    

    【讨论】:

    • 谢谢。这将适用于我的示例,其中 2 个 JsonViews 在属性上重叠。如果 Public 拥有 Private 没有且相反的属性怎么办。见上面的例子#2。
    • 编辑了我的答案。尝试在 @JsonView 注释中使用多个类,但没有运气。
    【解决方案2】:

    如果有人需要,可以找到更通用的案例。基本上,您可以使用不同的 JsonView 在 getter 中转换您的属性:

      @JsonView({ Views.Detail.class})
      public JsonNode getAgent() throws IOException {
          ObjectMapper mapper = new ObjectMapper();
          String json = mapper.writerWithView(Views. Private.class).writeValueAsString(agent);
          return mapper.readTree(json);
      }
    

    【讨论】:

      猜你喜欢
      • 2019-05-09
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多