当前位置: 首页 > 知识库问答 >
问题:

如何拥有两个具有不同命名空间和相同 JAXB 类的不同endpoint?

艾自强
2023-03-14

我用的是spring soap ws。

我有以下对应于复杂类型的JAXB域类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "reference",
    "reason"
})
@XmlRootElement(name = "request-message")
public class RequestMessageType {

    @XmlElement(name = "reference", required = true)
    protected String reference;
    @XmlElement(name = "reason")
    protected String reason;

   // I have getters and setters but removed here.
}

我有以下带有@XmlRegistry注释的类

@XmlRegistry
public class ObjectFactory {

    private final static QName _RequestMessage_QNAME = new QName("http://namespace/url", "request-message");

    public ObjectFactory() {
    }

    @XmlElementDecl(namespace = "http://namespace/url", name = "request-message")
    public JAXBElement<RequestMessageType> createDisconnectRequestMessage(RequestMessageType  value) {
        return new JAXBElement<RequestMessageType>(_RequestMessage_QNAME, RequestMessageType.class, null, value);
    }    
}

以下是endpoint

   @Endpoint
    public class FirstEndPoint {

        private static final String NAMESPACE_URI = "http://first/url/version";

        private static final Logger LOG = Logger.getLogger(FirstEndPoint.class);

        @PayloadRoot(namespace = NAMESPACE_URI, localPart = "request-message")
        @ResponsePayload
        public JAXBElement<ResponseMessageType> requestMessage(@RequestPayload JAXBElement<RequestMessageType> requestMessage) {
            LOG.info("request-message : first version ID : " + requestMessage.getValue().getReference());
        //Preparing response and return response 
        }
    }

    @Endpoint
    public class SecondEndPoint {

        private static final String NAMESPACE_URI = "http://second/url/version";
        private static final Logger LOG = Logger.getLogger(SecondEndPoint.class);


        @PayloadRoot(namespace = NAMESPACE_URI, localPart = "request-message")
        @ResponsePayload
        public JAXBElement<ResponseMessageType> requestMessage(@RequestPayload JAXBElement<RequestMessageType> requestMessage) {
            LOG.info("request-message : second version ID : " + requestMessage.getValue().getReference());
         //Preparing response and return response 

        }
    }

当我发出 Soap 请求时,我正在使用 soap 请求中的终结点中给出NAMESPACE_URI。

在这里,在这种情况下,我得到以下回应

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <SOAP-ENV:Fault>
            <faultcode>SOAP-ENV:Server</faultcode>
            <faultstring xml:lang="en">unexpected element (uri:"http://first/url/version", local:"request-message"). Expected elements are &lt;{http://namespace/url}request-message&gt;</faultstring>
        </SOAP-ENV:Fault>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

如果我使用"超文本传输协议://命名空间/url"作为NAMESPACE_URI在endpoint和肥皂请求我得到适当的响应,但我试图使它不同的两个endpoint与两个不同的命名空间,然后它不工作,并给出上述响应。

如何在同一个JAXB类中为两个不同的endpoint使用两个不同的名称空间?我对spring和web服务完全陌生。

附加信息:RequestMessageType类和ObjectFactory类在一个包中,在package-info.java命名空间中是

@javax.xml.bind.annotation.XmlSchema(namespace="http://namespace/url",elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.example

我需要更改package-info.java文件中的任何内容吗?

共有1个答案

龙宣
2023-03-14

我创建了一个示例项目。我希望它对你有用。你可以在这里看一下:https://github.com/angeloimm/spring-ws-sample 基本上这是我的WSDL文件(在SOAP Web Service中,一切都由WSDL统治):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:ss="http://www.example.org/SpringSample/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SpringSample"
    targetNamespace="http://www.example.org/SpringSample/">
    <wsdl:types>
        <xsd:schema targetNamespace="http://www.example.org/SpringSample/">
            <xsd:complexType name="abstractRequest">
                <xsd:sequence minOccurs="1" maxOccurs="1">
                    <xsd:element name="reqName" type="xsd:string" nillable="false"
                        maxOccurs="1" minOccurs="1" />
                </xsd:sequence>
            </xsd:complexType>
            <xsd:complexType name="abstractResponse">
                <xsd:sequence minOccurs="1" maxOccurs="1">
                    <xsd:element name="responseName" type="xsd:string"
                        nillable="false" maxOccurs="1" minOccurs="1" />
                </xsd:sequence>
            </xsd:complexType>
            <xsd:element name="requestImplementation" type="ss:abstractRequest" />
            <xsd:element name="responseImplementation" type="ss:abstractResponse" />
            <xsd:element name="requestImplementation2" type="ss:abstractRequest" />
            <xsd:element name="responseImplementation2" type="ss:abstractResponse" />
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="OperationRequest">
        <wsdl:part element="ss:requestImplementation" name="request" />
    </wsdl:message>
    <wsdl:message name="OperationResponse">
        <wsdl:part element="ss:responseImplementation" name="response" />
    </wsdl:message>
    <wsdl:message name="OperationRequest2">
        <wsdl:part element="ss:requestImplementation2" name="request2" />
    </wsdl:message>
    <wsdl:message name="OperationResponse2">
        <wsdl:part element="ss:responseImplementation2" name="response2" />
    </wsdl:message>
    <wsdl:portType name="SpringSample">
        <wsdl:operation name="Operation1">
            <wsdl:input message="ss:OperationRequest" />
            <wsdl:output message="ss:OperationResponse" />
        </wsdl:operation>
        <wsdl:operation name="Operation2">
            <wsdl:input message="ss:OperationRequest2" />
            <wsdl:output message="ss:OperationResponse2" />
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="SpringSampleSOAP" type="ss:SpringSample">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="Operation1">
            <soap:operation style="document" soapAction="http://www.example.org/SpringSample/Operation1" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="Operation2">
            <soap:operation style="document" soapAction="http://www.example.org/SpringSample/Operation2" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding> 
    <wsdl:service name="SpringSample">
        <wsdl:port binding="ss:SpringSampleSOAP" name="SpringSampleSOAP">
            <soap:address location="http://www.example.org/" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

如您所见,我定义了2种复杂类型:abstractRequestabstractACK。然后我通过使用元素Request est实作Request est实作2响应实作响应实作2来实现它们根据WS-I规范,您需要使用单独的操作和元素

然后我写了这个endpoint:

@Endpoint
public class SampleEndpoint
{
    private static final Logger logger = LoggerFactory.getLogger(SampleEndpoint.class.getName());
    private static final String NAME_SPACE_URI = "http://www.example.org/SpringSample/";

    @PayloadRoot(namespace = NAME_SPACE_URI, localPart="requestImplementation")
    @ResponsePayload
    public JAXBElement<AbstractResponse> operationOneResp(@RequestPayload JAXBElement<AbstractRequest> ar)
    {
        if( logger.isDebugEnabled() )
        {
            logger.debug("Operation 1 request "+ar.getValue().getReqName());
        }
        ObjectFactory of = new ObjectFactory();
        AbstractResponse aResp = of.createAbstractResponse();
        aResp.setResponseName("operation 1 response");
        JAXBElement<AbstractResponse> result = of.createResponseImplementation(aResp);
        return result;
    }
    @PayloadRoot(namespace = NAME_SPACE_URI, localPart="requestImplementation2")
    @ResponsePayload
    public JAXBElement<AbstractResponse> operationTwoResp(@RequestPayload JAXBElement<AbstractRequest> ar)
    {
        if( logger.isDebugEnabled() )
        {
            logger.debug("Operation 2 request "+ar.getValue().getReqName());
        }
        ObjectFactory of = new ObjectFactory();
        AbstractResponse aResp = of.createAbstractResponse();
        aResp.setResponseName("operation 2 response");
        JAXBElement<AbstractResponse> result = of.createResponseImplementation(aResp);
        return result;
    }
}

正如你现在看到的,我总是在这两个方法中使用< code>AbstractRequest和< code > abstract response JAXB element。这两种方法也可以在两个不同的endpoint中

我希望这是你需要的而且有用

安吉洛(男子名)

 类似资料:
  • 我从 3 个不同的客户端收到 3 个不同的 xml 输入: 来自客户端1的输入1:(命名空间前缀:,命名空间url:) 来自客户端 2 的输入 2:(命名空间前缀:,命名空间 URL:) 从客户端3输入3:(名称空间前缀: 时,< li >调用< code>String.replace() 这让我想到这种变量命名空间的方法是否应该完全可以接受。如果有什么可以改进此代码的方法,那么我要求社区在答案/

  • 我有一个react-native应用程序,带有react-native购买和react-native指示包。他们都有进口品 由:java.lang.runtimeException:com.android.builder.dexing.dexarchivEmergerException:合并dex归档时出错:在https://developer.android.com/studio/build/d

  • 问题内容: 如何在不同的程序包中访问两个具有相同名称的类? 和 所有这些都在同一个班级 谢谢。 问题答案: 您将必须导入另一个,您将编写完全合格的路径 例如在您的代码中:

  • 我需要加载XML文件,但存在两种相同的文件格式,只是名称空间不同-在我的简化示例中,: : 引用了一个特定的名称空间,因此我不能以相同的方式处理这两个文件: 给出输出: 目前,我已经以一种次优的方式进行了工作,通过使用https://stackoverflow.com/a/50800021-但如果可能的话,我想将其转移到JAXB中。 输出:

  • 假设您有2个包,并且有名为-Test的公共类。 第一个包。测试 第二包测试 它们中的每一个都有实例变量-x。 在第一种情况下-int x=2; 在第二种情况下-int x=3; 我想导入FirstPackage。在第二个包内测试。测试并打印值为2的x。 我的代码: 但是输出是3。如何打印?

  • 获取JAXB异常,如“两个类具有相同的XML类型名称…”, 以下是例外情况的详细信息: 异常在线程"main"com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsExcema: 1计数的IllegalAnnotationExceptions两个类有相同的XML类型名称"城市"。使用@XmlType.name和@XmlType.namespa