2017-08-09 70 views
10

我正在使用春天肥皂ws。我怎樣纔能有兩個不同的端點具有不同的命名空間和相同的JAXB類?

我有以下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 

     } 
    } 

當我做肥皂請求,我正在使用肥皂請求中的端點中給出的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> 

如果我在端點使用「http://namespace/url」作爲NAMESPACE_URI和SOAP請求,我得到適當的迴應,但我儘量做到針對不同兩個端點有兩個不同的命名空間,那麼它不起作用,並給出上述響應。

如何爲具有相同JAXB類的兩個不同端點使用兩個不同的名稱空間?我對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文件改變什麼?

+0

我會好好的也能看到你的生成WSDL 在我的模式我無論如何d定義兩個請求和響應元素。這些元素將是相同的類型。當我有時間時,如果你願意,我可以在我的github賬戶上共享一個簡單的項目 –

+0

我建議創建一個RequestMessageType摘要,並使它從2個類中擴展。這些課程單獨註冊。通過這樣做:您的wsdls將具有不同的名稱空間,但您的服務層可以保持不變。 –

回答

5

我創建了一個示例項目。我希望它對你有用。你可以給看看這裏: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; 
    } 
} 

正如你現在可以看到我總是在兩種方法中都使用AbstractRequestAbstractResponse JAXBElement。 2種方法,也可以在2個不同的端點

我希望這是你需要的東西,它是有用的

安傑洛

相關問題