2012-09-07 13 views
6

Utilizzo JAX RS per creare un servizio web REST utilizzando il solito @Path, @GET, @Produces({"application/json, "application/xml"}).JAX RS - JSON e XML Circolare/Errore di riferimento ciclico

Sto restituendo un POJO come risposta che viene inviato come JSON o XML a seconda del tipo di richiesta. Funzionava bene fino a quando ho aggiunto una relazione Molti-A-molti con un'altra entità. La relazione è bidirezionale.

Sto usando JBoss AS 7. Ho aggiunto Jackson @JsonManagedReference e @JsonBackReference ma senza alcun risultato.

Come superare questo?

ho schierato i miei JAX RS in questo modo: -

<?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>  

non mi estendo qualsiasi classe Application o utilizzato qualsiasi classe attivatore jaxrs.

Questo RESTEasy di JBoss utilizza Jackson come provider JSON, anche allora perché non riconosce le annotazioni @JsonManagedReference?

Devo aggiornare le dipendenze, se sì allora come? E come risolvere se la richiesta è di XML, anche qui fallisce nel riferimento circolare in JAXB.

Grazie in anticipo!

+1

Hai visto questa domanda? http://stackoverflow.com/questions/3073364/jaxb-mapping-cyclic-references-to-xml – Tomalak

+0

Grazie, ci sto lavorando, ma lascia ancora JSON allo scoperto, no? – Stuarty

+1

Immagino che ci debba essere un approccio analogo per JSON. (Non lo so, però. La domanda sembrava abbastanza simile, quindi ho voluto ricollegarli.) – Tomalak

risposta

4

Nota: Sono il lead EclipseLink JAXB (MOXy) e un membro del gruppo di esperti JAXB (JSR-222).

MOXy offre l'estensione @XmlInverseReference che può essere utilizzata per supportare le relazioni bidirezionali nel binding XML e JSON.


JAVA MODELLO

clienti

Customer ha una collezione di oggetti PhoneNumber.

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

Ogni oggetto PhoneNumber mantiene un puntatore di nuovo all'oggetto Customer. Questa proprietà è annotata con @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.proprietà

Per utilizzare moxy come provider JAXB è necessario includere un file chiamato jaxb.properties nello stesso pacchetto come il modello di dominio con la seguente voce (vedi: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

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

INPUT

Di seguito sono riportati i documenti che saranno unmarshal in questo esempio

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

} 

USCITA

Di seguito si riporta l'uscita dalla esecuzione del codice demo. Come si può vedere la proprietà customer viene popolata su tutti gli oggetti PhoneNumber.

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

PER ULTERIORI INFORMAZIONI