On demand lazy loading via dynamic @JsonIgnore annotation

与世无争的帅哥 提交于 2021-02-05 05:52:27

问题


I have something like:

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

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

PROBLEM: I pass MyEntity to the client as JSON string. But the problem is that I have two types of client's requests:

  1. I need to pass MyEntity with byte[] content array
  2. I need to pass MyEntity without byte[] content array

In first case I needn't @JsonIgnore annotation, in second - do need.

QUESTIONS:

  1. How to achive dynamical @JsonIgnore annotation? Is it possible at all?
  2. Any alternatives to achieve lazy loading?

P.S. As I understand, even if I mark my byte[] content array with lazy-load annotation, it will be loaded anyway when Jackson will parse MyEntity to JSON-string.

Thank you in advance!


回答1:


You can use Jackson views. Please, see my below example:

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) + "]";
    }
}

Above program prints:

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"}

As you can see, with basic view Jackson doesn't read content properties.




回答2:


As far as I know, it is impossible to make jackson to lazy load your property on demand. Maybe an alternative way is to create another value object, just copy the properties you want and drop that you don't want.



来源:https://stackoverflow.com/questions/17921963/on-demand-lazy-loading-via-dynamic-jsonignore-annotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!