【问题标题】:On demand lazy loading via dynamic @JsonIgnore annotation通过动态 @JsonIgnore 注释按需延迟加载
【发布时间】:2013-07-29 10:43:49
【问题描述】:

我有类似的东西:

@Entity
@Table(name = "myEntity")
public class MyEntity {
  //....

  @Column(name = "content")
  private byte[] content;
  //....
}

问题: 我将 MyEntity 作为 JSON 字符串传递给客户端。 但是问题是我有两种客户的请求:

  1. 我需要传递 MyEntity with byte[] content 数组
  2. 我需要传递 MyEntity 没有 byte[] 内容数组

在第一种情况下我不需要 @JsonIgnore 注释,在第二种情况下 - 确实需要。

问题

  1. 如何实现动态@JsonIgnore 注释?有可能吗?
  2. 实现延迟加载的任何替代方法?

附:据我了解,即使我用延迟加载注释标记了我的 byte[] 内容 数组,当杰克逊将 MyEntity 解析为 JSON 字符串时,它仍然会被加载。

提前谢谢你!

【问题讨论】:

  • 您可以在 ObjectMapper 对象上禁用 FAIL_ON_UNKNOWN_PROPERTIES 功能。之后,ObjectMapper 应该能够反序列化带有这个属性的 JSON。
  • 问题出在序列化中(当我用杰克逊序列化对象时,它会拉出所有延迟加载),但不在反序列化中

标签: json hibernate jackson lazy-loading


【解决方案1】:

您可以使用Jackson views。请看我下面的例子:

import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonProgram {

    public static void main(String[] args) throws IOException {
        Entity entity = new Entity();
        entity.setId(100);
        entity.setContent(new byte[] { 1, 2, 3, 4, 5, 6 });

        ObjectMapper objectMapper = new ObjectMapper();

        System.out.println("Generate JSON with basic properties: ");
        System.out.println(objectMapper.writerWithView(View.BasicView.class).writeValueAsString(entity));
        System.out.println("Generate JSON with all properties: ");
        System.out.println(objectMapper.writerWithView(View.ExtendedView.class).writeValueAsString(entity));
    }
}

interface View {

    interface BasicView {
    }

    interface ExtendedView extends BasicView {
    }
}

class Entity {

    @JsonView(View.BasicView.class)
    private int id;

    @JsonView(View.ExtendedView.class)
    private byte[] content;

    public byte[] getContent() {
        System.out.println("Get content: " + Arrays.toString(content));
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public int getId() {
        System.out.println("Get ID: " + id);
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Entity [id=" + id + ", content=" + Arrays.toString(content) + "]";
    }
}

上面的程序打印:

Generate JSON with basic properties: 
Get ID: 100
{"id":100}
Generate JSON with all properties: 
Get ID: 100
Get content: [1, 2, 3, 4, 5, 6]
{"id":100,"content":"AQIDBAUG"}

如您所见,在基本视图中,Jackson 不会读取 content 属性。

【讨论】:

  • 是的。但我必须写类似 oMapper.setSerializationConfig(oMapper.getSerializationConfig() .withView(View.BasicView.class));但在 fastxml jackson 中没有 setSerializationConfig 方法
  • 能否提供生成json的基本属性代码?
  • 为什么不想使用 objectMapper.writerWithView(View.BasicView.class) 方法?
  • 谢谢,我不知道那个方法。非常感谢你!
  • 没问题。很高兴为您提供帮助。
【解决方案2】:

据我所知,让杰克逊按需延迟加载您的财产是不可能的。也许另一种方法是创建另一个值对象,只需复制您想要的属性并删除您不想要的属性。

【讨论】:

  • 但是 json viewa 和自定义序列化过滤器怎么样?
  • 延迟加载是 Hibernate 等 ORM 工具的一项功能。您绝对可以按照@michal-ziober 的建议使用视图和过滤器来自定义您的 json 字符串。
猜你喜欢
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 2014-11-01
  • 1970-01-01
  • 2011-03-03
  • 2017-11-02
  • 1970-01-01
相关资源
最近更新 更多