2017-08-09 45 views
10

Tôi đang sử dụng xà phòng mùa xuân.Làm cách nào để có hai điểm cuối khác nhau với không gian tên khác nhau và cùng một lớp JAXB?

Tôi đã sau lớp miền JAXB tương ứng với các loại phức tạp

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

Tôi có lớp sau đây với các chú thích @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); 
    }  
} 

Sau đây là các điểm cuối

@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 

     } 
    } 

Khi tôi làm xà phòng yêu cầu, tôi đang sử dụng NAMESPACE_URI được cung cấp trong các điểm cuối trong yêu cầu xà phòng.

Ở đây, trong trường hợp này, tôi nhận được sau phản ứng

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

Nếu tôi sử dụng "http://namespace/url" như NAMESPACE_URI trong thiết bị đầu cuối và trong yêu cầu xà phòng tôi nhận được câu trả lời đúng đắn nhưng tôi cố gắng để làm cho nó khác nhau cho hai điểm cuối với hai không gian tên khác nhau thì nó không hoạt động và đưa ra phản hồi ở trên.

Làm cách nào để sử dụng hai không gian tên khác nhau cho hai điểm cuối khác nhau với cùng một lớp JAXB? Tôi hoàn toàn mới vào mùa xuân và dịch vụ web.

Thông tin thêm: lớp RequestMessageType và lớp ObjectFactory là trong một gói và trong namespace package-info.java là

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

Tôi có cần phải thay đổi bất cứ điều gì trong tập tin package-info.java?

+0

tôi sẽ là tốt để xem cũng WSDL được tạo của bạn Trong bất kỳ trường hợp trong lược đồ của tôi tôi d xác định hai phần tử yêu cầu và đáp ứng. Những yếu tố này sẽ cùng loại. Khi tôi có thời gian nếu bạn muốn tôi có thể chia sẻ một dự án đơn giản trên tài khoản github của tôi –

+0

Tôi khuyên bạn nên tạo một bản tóm tắt RequestMessageType và tạo 2 lớp để mở rộng từ nó. Những lớp học đó đăng ký một cách riêng biệt.Bằng cách đó: các wsdls của bạn sẽ có các không gian tên khác nhau, nhưng lớp dịch vụ của bạn có thể được giữ nguyên chưa sửa đổi. –

Trả lời

5

Tôi đã tạo một dự án mẫu. Tôi hy vọng nó có thể hữu ích cho bạn. Bạn có thể cung cấp một cái nhìn vào nó ở đây: https://github.com/angeloimm/spring-ws-sample Về cơ bản đây là tập tin WSDL của tôi (trong Dịch vụ SOAP Web tất cả được cai trị bởi 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> 

Như bạn có thể thấy tôi định nghĩa 2 loại phức tạp: abstractRequestabstractResponse. Sau đó, tôi thực hiện chúng bằng cách sử dụng các yếu tố requestImplementation, requestImplementation2, responseImplementation, responseImplementation2 Theo WS-I đặc điểm kỹ thuật bạn cần phải sử dụng các hoạt động và các yếu tố

Sau đó, riêng tôi đã viết endpoint này:

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

Như bạn có thể thấy bây giờ tôi luôn sử dụng AbstractRequestAbstractResponse JAXBElement trong cả hai phương pháp. 2 phương pháp này cũng có thể ở 2 điểm cuối khác nhau

Tôi hy vọng đó là những gì bạn cần và hữu ích

Angelo

Các vấn đề liên quan