2013-06-30 22 views
11

Posiadam i wydaje się odniesienie do Circular.Json i Java - Circular Reference

mam Rest sieciowe która zwraca obiekty do przedniego końca, problem jest gdy próbuję powrócić obiekty, które mają kilka odniesień tak w wyniku uzyskać nieskończoną odpowiedź, które generują

java.lang.IllegalStateException: 
    Cannot call sendError() after the response has been committed 

obiektów są generowane automatycznie przez generowanie kodu hibernacji i muszę mieć odwołanie cykliczne w zapleczu, po prostu muszę usunąć je przed wysłaniem informacji do frontendu za pomocą Jacksona.

Metoda kontroler jest nagłówek:

@RequestMapping(value="/list", method=RequestMethod.POST) 
public @ResponseBody eventResponse list(@RequestBody String sessionID) { 

Nie robię niczego explicite przekonwertować do formatu JSON, jestem Newby z tym i myślę, że Jackson rozwiązana to automatycznie.

+1

http://wiki.fasterxml.com/JacksonFeatureBiDirReferences –

Odpowiedz

23

Można to zrobić na dwa sposoby. Jeśli musisz ujawnić swój podmiot światu zewnętrznemu, polecam dodać @JsonIgnore do właściwości, która powoduje odwołanie cykliczne. Dzięki temu Jackson nie będzie serializować tej właściwości.

Innym sposobem jest użycie funkcji dwukierunkowych udostępnianych przez Jacksona. Możesz użyć @JsonManagedReference lub @JsonBackReference. @JsonManagedReference to część "do przodu", która zostanie standardowo przekształcona do postaci szeregowej. @JsonBackReference jest "tylną" częścią odniesienia; nie będzie serializowany, ale zostanie zrekonstruowany, gdy typ "forward" zostanie zserializowany.

Możesz sprawdzić przykłady here.

To odpowiada na twój komentarz: Myślę, że możesz chcieć w tym przypadku użyć DTO, który jest widoczny dla świata zewnętrznego. Podoba mi się to podejście, ponieważ nie chcę ujawniać moich jednostek na zewnątrz. Oznacza to, że adnotacje Jacksona trafiłyby do DTO, a nie do enity. Potrzebowałbyś jakiegoś rodzaju odwzorowującego lub konwertującego, który przekształca jednostkę w DTO. Teraz, kiedy dokonasz zmian w swoim podmiocie, nie będą one propagowane do DTO, chyba że zmodyfikujesz swój odwzornik/konwerter. Myślę, że to jest w porządku, ponieważ kiedy dokonasz zmiany w swoim podmiocie, możesz zdecydować, czy chcesz, aby ta zmiana została ujawniona, czy nie.

UPDATE

Jest dobry blogu here że idzie się w szczegóły na temat różnych sposobów można obsługiwać relacje dwukierunkowych w Jackson. Opisuje rozwiązania, które wykorzystują także i serializator niestandardowy. Jest to dość obszerny zapis różnych technik, z których możesz skorzystać.

+0

Tak, czytam o tym. Ale chodzi o to, że nie chcę "dotykać" jednostek generowanych przez Hibernate. Ponieważ baza danych ciągle się powiększa, więc za każdym razem, gdy dodam coś, będę musiał ponownie zmodyfikować wszystkie encje. Jak rozumiem, muszę zmodyfikować obiekty dla obu opcji, prawda? – Faabass

+0

Dlaczego upadek? –

5

Pojedyncza adnotacja @JsonIdentityInfo rozwiązuje problem. Obsługuje również odwołania kołowe. Reference

+0

Jedynym problemem jest sytuacja, w której pole tożsamości ma wartość NULL. następnie wracasz do kwadratu 1 - odwołanie cykliczne. – anton1980