首页 文章

JAX RS - JSON和XML循环/循环引用错误

提问于
浏览
6

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

我正在返回一个POJO作为响应,它根据请求的类型以JSON或XML的形式发送 . 它工作正常,直到我与另一个实体添加了 Many-To-Many 关系 . 这种关系是双向的 .

我正在使用 JBoss AS 7 . 我添加了 Jackson 的 @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中的循环引用中失败 .

提前致谢!

1 回答

  • 4

    Note: 我是EclipseLink JAXB (MOXy)领导,是JAXB (JSR-222)专家组的成员 .

    MOXy 提供了 @XmlInverseReference 扩展,可用于支持XML和JSON绑定中的双向关系 .


    JAVA MODEL

    Customer

    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.properties

    要将MOXy用作JAXB提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,并带有以下条目(请参阅: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

    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 对象上 .

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

    FOR MORE INFORMATION

相关问题