2016-08-16 8 views
0

を解決するために、私はTag.java有する:ジャクソンどのように循環参照

public class Tag{ 
    private List<Tag> links; 
} 

今A、B、Cの実体、リンクB(BリンクAを意味する)、Cと、 BリンクA、C、CリンクA、B

jsonを第1レベルのシリアル番号linksにシリアル化する方法を教えてください。

+0

あなたが欲しいものをわかりません。 –

+0

入力と期待出力を表示できますか? –

答えて

0

私はJackson's custom serializer

を通じてソリューションを実現することができた私は、タグのインスタンスを識別するための名前を追加し、シリアライザクラスを指定注釈:以下

@JsonSerialize(using = TagJsonSerializer.class) 
public class Tag 
{ 
    public String name; 
    public List<Tag> links = new ArrayList<>(); 
} 

は、シリアライザです。 "links"の下では、このように循環参照を避け、タグの名前を書き込みます:

public class TagJsonSerializer extends JsonSerializer<Tag> 
{ 
    @Override 
    public void serialize(Tag value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException 
    { 
     try { 
      jgen.writeStartObject(); 
      jgen.writeFieldName("name"); 
      jgen.writeObject(value.name); 
      jgen.writeFieldName("links"); 
      Object[] tagNames = value.links.stream().map(tag -> tag.name) 
        .collect(Collectors.toList()).toArray(); 
      jgen.writeObject(tagNames); 
      jgen.writeEndObject(); 
      return; 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

試験方法:

public static void main(String... args) 
{ 
    Tag a = new Tag(); 
    Tag b = new Tag(); 
    Tag c = new Tag(); 
    a.name = "A"; 
    a.links.add(b); 
    a.links.add(c); 
    b.name = "B"; 
    b.links.add(a); 
    b.links.add(c); 
    c.name = "C"; 
    c.links.add(a); 
    c.links.add(b); 

    ObjectMapper mapper = new ObjectMapper(); 
    try { 
     mapper.writeValue(System.out, a); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

出力:

{"name":"A","links":["B","C"]}