2012-09-07 3 views
6

JAX RS를 사용하여 보통 @Path, @GET, @Produces({"application/json, "application/xml"})을 사용하여 REST 웹 서비스를 만듭니다.JAX RS - JSON 및 XML 순환/순환 참조 오류

요청 유형에 따라 JSON 또는 XML로 보내지는 응답으로 POJO를 반환합니다. Many-To-Many 다른 엔터티와의 관계를 추가 할 때까지 제대로 작동했습니다. 그 관계는 양방향입니다.

나는 JBoss AS 7을 사용하고 있습니다. 나는 잭슨의 @JsonManagedReference@JsonBackReference을 추가했지만 아무 소용이 없습니다.

어떻게 해결할 수 있습니까?

내가 이렇게 내 JAX의 RS를 구축 : -
<?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>  

나는 어떤 응용 프로그램 클래스를 확장하거나 JAXRS 활성제 클래스를 사용하지 않았다.

이 JBoss의 RESTEasy는 Jackson을 JSON 공급자로 사용하고 있습니다. 그럼에도 불구하고 @JsonManagedReference 주석을 인식하지 못하는 이유는 무엇입니까?

종속성을 업데이트해야합니까? 그렇다면 어떻게해야합니까? 요청이 XML 인 경우이를 수정하는 방법도 있습니다. JAXB의 순환 참조에서도 실패합니다.

미리 감사드립니다.

+1

이 질문을 본 적이 있습니까? http://stackoverflow.com/questions/3073364/jaxb-mapping-cyclic-references-to-xml – Tomalak

+0

감사합니다. 아직 조사 중이지만 아직 JSON이 공개되지 않고 있습니다. – Stuarty

+1

JSON에 대한 유사한 접근 방식이 있어야한다고 생각합니다. (나는 모르지만 질문은 합리적으로 비슷하게 들렸다. 그래서 나는 그것들을 cross-link하고 싶었다.) – Tomalak

답변

4

참고 : 저는 EclipseLink JAXB (MOXy)이며 JAXB (JSR-222) 전문가 그룹의 멤버입니다.

MOXy은 XML과 JSON 바인딩에서 양방향 관계를 지원하는 데 사용할 수있는 @XmlInverseReference 확장을 제공합니다.


자바 모델

고객

CustomerPhoneNumber 개체의 컬렉션을 가지고있다.

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

PhoneNumber 객체는 Customer 개체에 다시 포인터를 유지합니다. 이 속성은 @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.속성

는 다음과 같은 항목으로 도메인 모델과 동일한 패키지에 jaxb.properties라는 파일을 포함 할 필요가 당신의 JAXB 공급자로 MOXY을 사용하려면 (참조 : http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html를)

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

INPUT

아래 예제는이 예제에서 언 마샬링 할 문서입니다.

,

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

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

} 

OUTPUT 아래

데모 코드를 실행 한 출력됩니다. 보는 바와 같이 customer 속성은 모든 PhoneNumber 개체에 채워집니다. 자세한 내용은

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