【问题标题】:Web Service cycle using Contract-First in Java在 Java 中使用 Contract-First 的 Web 服务循环
【发布时间】:2023-03-24 19:38:02
【问题描述】:

我正在开发具有合同优先网络服务(wsimportjaxws-maven-plugin)的应用程序。

我应该如何编写 WSDL/XSD 文件以便能够处理周期?例如对象 department 引用 employeesemployee 引用 department (如本文中的 http://jaxb.java.net/guide/Mapping_cyclic_references_to_XML.html )。文章注释了@XmlTransient 注释,但由于我使用契约优先,我无法以任何方式修改生成的类。

如果我只是忽略这些循环,那么在我第一次运行 web 服务时,我会收到如下错误:

Caused by: com.sun.istack.SAXException2: 
A cycle is detected in the object graph. This will cause infinitely deep XML: 
Employee@18ac4d8 -> Department@aa35d5 -> Employee@18ac4d8

【问题讨论】:

    标签: java web-services xsd wsdl jax-ws


    【解决方案1】:

    问题是 Web 服务契约(至少是 WS-I Basic Profile 兼容的契约)不能对消息中对其他对象的引用进行编码。也就是说,引用类型的字段总是通过编组它所引用的对象的字段来编组。如果对象图包含循环,则此递归是无限的。

    也就是说,如果你有:

    class A {
        String name;
        A a;
    }
    

    并且做到了:

    A a = new A();
    a.name = "hello";
    a.a = a;
    marshall(a);
    

    XML 看起来像

    <a>
        <name>hello</name>
        <a>
            <name>hello</name>
            <a>
                <name>hello</name>
                <a>
                    ...
    

    为避免这种情况,需要打破循环。典型的方法包括使关联只能在一个方向上导航,在编组之前将反向引用设置为null(让接收者重建它们),将关联移动到单独的类中,如

    class A {
        String name;
    }
    class B {
        String adress;   
    }
    
    class AWithB {
        A a;
        B b;
    }
    

    还有许多其他选项。

    【讨论】:

    • 感谢回复,这是解决问题的一种方法,但它需要在通信双方额外的代码(服务器必须打破引用,客户端重建它)。我试图研究@XmlID/@XmlIDREF,它启用循环引用,但它将对象转换为对象类,并且还需要在客户端进行手动类型转换..
    • 我的立场是正确的,感谢您指出 xs:id 和 xs:idref。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    相关资源
    最近更新 更多