有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java我怎么能有两个具有不同名称空间和相同JAXB类的不同端点?

我正在使用springsoapws

我有以下与复杂类型对应的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
    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请求中端点中给定的名称空间_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>

如果我在端点和soap请求中使用“http://namespace/url”作为名称空间URI,我会得到正确的响应,但我试图使具有两个不同名称空间的两个端点的响应不同,那么它不起作用,并给出上述响应

如何为具有相同JAXB类的两个不同端点使用两个不同的名称空间?我对spring和web服务完全陌生

附加信息:RequestMessageType类和ObjectFactory类位于一个包和包信息中。java名称空间是

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

我是否需要更改包裹信息中的任何内容。java文件


共 (1) 个答案

  1. # 1 楼答案

    我创建了一个示例项目。我希望它能对你有用。你可以在这里看一下:https://github.com/angeloimm/spring-ws-sample 基本上,这是我的WSDL文件(在SOAP Web服务中,所有内容都由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个复杂类型:abstractRequestabstractResponse。然后我通过使用元素requestImplementationrequestImplementation2responseImplementationresponseImplementation2来实现它们。根据WS-I规范,您需要使用单独的操作和元素

    然后我写了这个端点:

    @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;
        }
    }
    

    正如您现在看到的,我总是在这两种方法中使用AbstractRequestAbstractResponseJAXBElement。这两种方法也可以位于两个不同的端点中

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

    安杰洛