2012-09-07 10 views
6

Używam JAX RS do utworzenia usługi sieciowej REST przy użyciu zwykłego @Path, @GET, @Produces({"application/json, "application/xml"}).JAX RS - JSON i XML Błąd referencyjny cykliczny/cykliczny

Zwracam POJO jako odpowiedź, która jest wysyłana jako JSON lub XML w zależności od typu żądania. Wszystko działało dobrze, dopóki nie dodałem relacji z wieloma osobami do innej jednostki. Związek jest dwukierunkowy.

Używam JBoss AS 7. Dodałem Jackson'a @JsonManagedReference i @JsonBackReference, ale bez skutku.

Jak do tego przejść?

I wdrożone moje JAX RS tak: -

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0"> 
    <servlet> 
     <servlet-name>javax.ws.rs.core.Application</servlet-name> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>javax.ws.rs.core.Application</servlet-name> 
     <url-pattern>/rest/*</url-pattern> 
    </servlet-mapping> 
</web-app>  

nie przedłużyć każdą klasę aplikacji lub stosować dowolną klasę aktywator JAXRS.

Ten JBoss's RESTEasy używa Jacksona jako dostawcy JSON, nawet wtedy, gdy nie rozpoznaje adnotacji @JsonManagedReference?

Czy muszę aktualizować zależności, jeśli tak, to w jaki sposób? A jak naprawić, jeśli żądanie jest z XML, tam też nie powiedzie się w odwołaniu kołowym w JAXB.

Z góry dziękuję!

+1

Widziałeś to pytanie? http://stackoverflow.com/questions/3073364/jaxb-mapping-cyclic-references-to-xml – Tomalak

+0

Dzięki, patrzę na to, ale nadal pozostawia JSON-a na otwartej przestrzeni, nie? – Stuarty

+1

Zgaduję, że musi istnieć analogiczne podejście do JSON. (Nie wiem, ale pytanie brzmiało dość podobnie, więc chciałem je połączyć.) – Tomalak

Odpowiedz

4

Uwaga: Jestem EclipseLink JAXB (MOXy) ołowiu i członkiem grupy JAXB (JSR-222) ekspertów.

MOXy oferuje rozszerzenie @XmlInverseReference, które może być używane do obsługi relacji dwukierunkowych w powiązaniu XML i JSON.


JAVA MODEL

klienta

Customer posiada kolekcję PhoneNumber obiektów.

package forum12312395; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
public class Customer { 

    private List<PhoneNumber> phoneNumbers; 

    @XmlElement(name="phone-number") 
    public List<PhoneNumber> getPhoneNumbers() { 
     return phoneNumbers; 
    } 

    public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) { 
     this.phoneNumbers = phoneNumbers; 
    } 

} 

PhoneNumber

Każdy PhoneNumber obiekt utrzymuje powrotem wskaźnik do obiektu Customer. Ta właściwość opatrzona jest komentarzem: @XmlInverseReference.

package forum12312395; 

import javax.xml.bind.annotation.XmlValue; 
import org.eclipse.persistence.oxm.annotations.XmlInverseReference; 

public class PhoneNumber { 

    private String value; 
    private Customer customer; 

    @XmlValue 
    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 

    @XmlInverseReference(mappedBy="phoneNumbers") 
    public Customer getCustomer() { 
     return customer; 
    } 

    public void setCustomer(Customer customer) { 
     this.customer = customer; 
    } 

} 

JAXB.Właściwości

Aby korzystać Moxy jako dostawcę JAXB musisz dołączyć plik o nazwie jaxb.properties w tym samym opakowaniu jak model domeny z następującego wpisu (patrz: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

INPUT

Poniżej znajdują się dokumenty, które zostaną ujawnione w tym przykładzie:

input.xml

<?xml version="1.0" encoding="UTF-8"?> 
<customer> 
    <phone-number>555-WORK</phone-number> 
    <phone-number>555-HOME</phone-number> 
</customer> 

input.json

{ 
    "customer" : { 
     "phone-number" : ["555-HOME", "555-WORK"] 
    } 
} 

DEMO

package forum12312395; 

import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 
import org.eclipse.persistence.jaxb.UnmarshallerProperties; 
import org.eclipse.persistence.oxm.MediaType; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Customer.class); 

     // JSON 
     Unmarshaller jsonUnmarshaller = jc.createUnmarshaller(); 
     jsonUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
     StreamSource json = new StreamSource("src/forum12312395/input.json"); 
     Customer customerFromJSON = (Customer) jsonUnmarshaller.unmarshal(json); 
     for(PhoneNumber phoneNumber : customerFromJSON.getPhoneNumbers()) { 
      System.out.println(phoneNumber.getCustomer()); 
     } 

     // XML 
     Unmarshaller xmlUnmarshaller = jc.createUnmarshaller(); 
     StreamSource xml = new StreamSource("src/forum12312395/input.xml"); 
     Customer customerFromXML = (Customer) xmlUnmarshaller.unmarshal(xml); 
     for(PhoneNumber phoneNumber : customerFromXML.getPhoneNumbers()) { 
      System.out.println(phoneNumber.getCustomer()); 
     } 
    } 

} 

WYJŚCIE

Poniżej jest wyjście z uruchomieniem kodu demo. Jak widać właściwość customer jest wypełniona na wszystkich obiektach PhoneNumber.

[email protected] 
[email protected] 
[email protected] 
[email protected] 

WIĘCEJ informacji

Powiązane problemy