6

我正在使用 JAX RS 使用通常的@Path, @GET, @Produces({"application/json, "application/xml"}).

我返回一个 POJO 作为响应,根据请求的类型以 JSON 或 XML 形式发送。在我添加与另一个实体的多对多关系之前,它工作正常。这种关系是双向的。

我正在使用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>    

我没有扩展任何 Application 类或使用任何 JAXRS 激活器类。

这个 JBoss 的 RESTEasy 使用 Jackson 作为他们的 JSON 提供者,即使那样它为什么不识别@JsonManagedReference注释?

我是否必须更新依赖项,如果是,那么如何?以及如何解决如果请求是 XML 的,那么它在 JAXB 中的循环引用中也失败了。

提前致谢!

4

1 回答 1

5

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

MOXy offers the @XmlInverseReference extension that can be used to support bidirectional relationships in both XML and JSON binding.


JAVA MODEL

Customer

Customer has a collection of PhoneNumber objects.

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

Each PhoneNumber object maintains a back pointer to the Customer object. This property is annotated with @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.properties

To use MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

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

INPUT

Below are the documents that we will unmarshal in this example

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

}

OUTPUT

Below is the output from running the demo code. As you can see the customer property is populated on all of the PhoneNumber objects.

forum12312395.Customer@3ef38fd1
forum12312395.Customer@3ef38fd1
forum12312395.Customer@320eef20
forum12312395.Customer@320eef20

FOR MORE INFORMATION

于 2012-09-07T10:28:14.227 回答