2016-01-07 24 views
0

首先,抱歉我的英语不好;使用双向JACKSON

其次,我有以下代码:

@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”的信息在第一种情况下,但在第二个我需要“客户”信息,但我不希望他的“vendas”,因为我已经得到它;

我已经trid @JsonIgnore并没有为我工作,我该怎么办? PS:我正在使用GSON从JSON获取.Class,并且我得到了一个可怕的异常,因为有时候客户端是一个对象,有时是整数,所以如果你们有另一个解决方案让客户端和服务器端不改变他们的类型,我也会知道。 :(

+0

可以使用Gson或Jackson。不是 –

+0

@ cricket_007我会只使用杰克逊进行新的测试,之后,我会回来并显示结果。 –

回答

0

我能用Jackson的Mix-in feature解决这个问题。Mixin特性是一个类,你可以指定json注释(类,字段和getters/setters),它们适用于你序列化的bean/pojo。基本上,一个混合允许在运行时,没有chaning豆/ POJO源代码文件中添加批注。您可以使用杰克逊module feature在运行时应用的一个mixin。

所以我创建了一个混入动态地将@JsonIgnore注释vendas getter方法UserAccount类,另一个mixin将@JsonIgnore注释添加到Venda类的客户端获取方法。

下面是修改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} 
+0

首先,感谢您的帮助,但我想要的是这样的: 文达:(已过滤) {“id”:1,“cliente”:{“id”:1}} –

0

谢谢你们,我通过这种方式解决:

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); 

} 

}

和我和文达班加这样的:

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

所以......我我想要的JSON!