【问题标题】:Working with bi-dirctional JACKSON使用双向 JACKSON
【发布时间】:2016-01-07 01:28:17
【问题描述】:

首先,对不起我的英语不好;

其次,我有以下代码:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")    

public class UserAccount implements Serializable  {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private List<Venda> vendas;

    }

还有以下内容:

public class Venda implements Serializable  {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private UserAccount cliente;

    }

所以,一切都好,并以这种方式从序列化中获取 json(当我要求 UserAccount 时):

[
  {
    "id": 1,    
    "vendas": [
      {
        "id": 1,        
        "cliente": 1,        
      }
    ]
  }
]

当我要文达时:

[
  {
    "id": 1,    
    "cliente": {
      "id": 1,      
      "vendas": [
        {
          "id": 1,        
          "cliente": 1         
        }
      ]
    }
  }
]

问题是,在第一种情况下,我不需要“vendas”上的“cliente”信息,但在第二种情况下,我需要“cliente”信息,但是我不想要他的“vendas”,因为我之前已经拿到了;

我已经尝试过@JsonIgnore 并没有为我工作,我该怎么办?

PS:我正在与 GSON 合作从 JSON 中获取 .Class,但我得到了一个可怕的异常,因为有时客户是一个对象,有时是整数,所以如果你们有另一个解决方案,让客户和供应商不要'不要改变他们的类型,我也想知道。 :(

【问题讨论】:

  • 使用 Gson 或 Jackson。不是两者都
  • @cricket_007 我将只使用 Jackson 进行新的测试,之后我会回来展示结果。

标签: java json jackson gson bidirectional


【解决方案1】:

我可以使用 Jackson 的 Mix-in feature 解决这个问题。 Mixin 功能是一个类,您可以指定 json 注释(在类、字段和 getter/setter 上),它们适用于您序列化的 bean/pojo。基本上,mixin 允许在运行时添加注释,而无需更改 bean/pojo 源文件。您使用 Jackson 的 module feature 在运行时应用 Mixin。

因此,我创建了一个 mixin,将 @JsonIgnore 注释动态添加到 UserAccount 类的 vendas getter 方法,另一个 mixin 将 @JsonIgnore 注释添加到 Venda 类的 cliente getter 方法。

这里是修改后的UserAccount 类:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class UserAccount implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private List<Venda> vendas = new ArrayList<>();

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public List<Venda> getVendas() { return vendas; }
    public void        setVendas(List<Venda> vendas) { this.vendas = vendas; }
    public void        addVenda(Venda v) { 
        this.vendas.add(v);
        v.setCliente(this);
    }

    /**
     * a Jackson module that is also a Jackson mixin 
     * it adds @JsonIgnore annotation to getVendas() method of UserAccount class
     */
    public static class FilterVendas extends SimpleModule {
        @Override
        public void setupModule(SetupContext context) {
            context.setMixInAnnotations(UserAccount.class, FilterVendas.class);
        }
        // implementation of method is irrelevant. 
        // all we want is the annotation and method's signature 
        @JsonIgnore
        public List<Venda> getVendas() { return null; }  
    }

这里是修改后的Venda类:

public class Venda implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private UserAccount cliente;

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public UserAccount getCliente() { return cliente; }
    public void        setCliente(UserAccount cliente) { this.cliente = cliente; }

    /**
     * a Jackson module that is also a Jackson mixin 
     * it adds @JsonIgnore annotation to getCliente() method of Venda class
     */
    public static class FilterCliente extends SimpleModule {
        @Override
        public void setupModule(SetupContext context) {
            context.setMixInAnnotations(Venda.class, FilterCliente.class);
        }
        // implementation of method is irrelevant. 
        // all we want is the annotation and method's signature 
        @JsonIgnore
        public UserAccount getCliente() { return null; }
    }
}

以及带有运行时对象映射器配置的测试方法:

public static void main(String... args) {
    Venda v = new Venda();
    UserAccount ua = new UserAccount();
    v.setId(1L);
    ua.setId(1L);
    ua.addVenda(v);
    try {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println("UserAccount: (unfiltered)");
        System.out.println(mapper.writeValueAsString(ua));

        mapper = new ObjectMapper();
        // register module at run time to apply filter
        mapper.registerModule(new Venda.FilterCliente());
        System.out.println("UserAccount: (filtered)");
        System.out.println(mapper.writeValueAsString(ua));

        mapper = new ObjectMapper();
        System.out.println("Venda: (unfiltered)");
        System.out.println(mapper.writeValueAsString(v));

        mapper = new ObjectMapper();
        // register module at run time to apply filter
        mapper.registerModule(new UserAccount.FilterVendas());
        System.out.println("Venda: (filtered)");
        System.out.println(mapper.writeValueAsString(ua));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

输出:

UserAccount: (unfiltered)
{"id":1,"vendas":[{"id":1,"cliente":1}]}
UserAccount: (filtered)
{"id":1,"vendas":[{"id":1}]}
Venda: (unfiltered)
{"id":1,"cliente":{"id":1,"vendas":[{"id":1,"cliente":1}]}}
Venda: (filtered)
{"id":1}

【讨论】:

  • 首先,感谢您的帮助,但我想要的是:Venda: (filtered) {"id":1,"cliente":{"id":1}}
【解决方案2】:

谢谢大家,我通过这种方式得到了解决方案:

public class CustomClienteSerializer extends JsonSerializer<UserAccount> {

@Override
public void serialize(UserAccount cliente, JsonGenerator generator, SerializerProvider provider)
        throws IOException, JsonProcessingException {

    cliente.setVendas(null);
    generator.writeObject(cliente);

}

}

并将其添加到我的 venda 类中:

@JsonSerialize(using = CustomClienteSerializer.class)   
@ManyToOne(fetch = FetchType.EAGER)
private UserAccount cliente;

所以...我得到了我想要的 json!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-13
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 2016-07-02
    • 2019-09-10
    • 2018-05-13
    相关资源
    最近更新 更多