Announcement Announcement Module
Collapse
No announcement yet.
Endpoint mappings - methods with the same payloads Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Endpoint mappings - methods with the same payloads

    Hi guys,

    I have several interfaces and each of them have a number of methods. I have recently exposed one of them as a Web Service and tested it with SOAP UI, to demonstrate that it would easier to perform such component testing as compared to an existing tool that we have.

    So I have one EndPoint mapped and it exposed only one method so far. I now wanted to expose more methods and since they take the same parameters

    Code:
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "CustomerSearchRequest")
    	@ResponsePayload
    	@Transactional(readOnly=true)
    	public SearchCustomerResponse method2(@RequestPayload Element customerSearchOptions) 
    		throws JDOMException, JAXBException{
    Code:
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "CustomerSearchRequest")
    	@ResponsePayload
    	@Transactional(readOnly=true)
    	public SearchCustomerResponse method1(@RequestPayload Element customerSearchOptions) 
    		throws JDOMException, JAXBException
    I end up with an error when trying to access the Web Service

    org.springframework.context.ApplicationContextExce ption: Cannot map endpoint [public com.
    etc.SearchCustomerResponse com.etc.CustomerSearchEndPoint.method2(org.jdom2.E lement) throws org.jdom2.JDOMException,javax.xml.bind.JAXBExcepti on] on registration key [{http://www.etc.com/et/schemas/1/00}CustomerSearchRequest]: there's already endpoint [public com.etc.SearchCustomerResponse com.etc.CustomerSearchEndPoint.method1(org.jdom2.E lement) throws org.jdom2.JDOMException,javax.xml.bind.JAXBExcepti on] mapped

    My question is how would you suggest I expose multiple methods on the same EndPoint, with different names
    but with the same parameter and return type?

    Also, what do you think of the approach? Would you normally have an interfaces' methods on 1 endpoint, or would you have 1 EndPoint for each method. That would be a real pain in my case.


    Cheers
    Kris

  • #2
    You have to use something unique to map the different endpoints, if the endpoints have the same payload there must be something else you can identify them with. You would have to use that as a mapping.

    Comment


    • #3
      Hi Maarten,
      thanks for always taking the time to reply.

      If I wanted to identify them through the method name, which would always be different (otherwise it won't even compile), how should I change my configurations.


      Best regards
      Kris

      Comment


      • #4
        It has nothing to do with your method name or whatever... You need to identify the incoming request a webservice isn't a remote method invocation. So how to determine which method to call depends on the incoming request/action or whatever means you use to issue a request. This is based on the WSDL/XSD so it depends on the unique identifiers in there.

        Comment


        • #5
          Hi Maarten,

          you are totally right, this is not a remote call. But I want to expose the various methods as operations and which are only going to have the method name as a difference. Parameters are going to be the same.

          My WSDL is auto-generated and my configuration is as follows :

          Code:
           <sws:dynamic-wsdl id="cusSearchServiceInterface"  
              	portTypeName="CusSearchServicePort"                                                         
              	locationUri="http://aserversomewhere:8080/customerSearchService/"                                                       
             		 targetNamespace="http://www.acompany/definitions">      
             		                          
            		<sws:xsd location="/WEB-INF/cus-request.xsd"/>                                                  
          	</sws:dynamic-wsdl>
          Also, since I have
          Code:
          <sws:annotation-driven/>
          defined, it will automatically use
          Code:
          PayloadRootAnnotationMethodEndpointMapping
          . The latter uses the parameters/Payload to differentiate the operations and this is what is causing the issue, and using the same key for more than 1 method.

          If there was a way for me to use another mapping and to modify that mapping such that it would consider my methods as different operations, then that would be the solution.

          So, I guess the question actually is : is there a mapper already available for my scenario or should I write a new one.

          Thanks a lot for your time
          Kris

          Comment


          • #6
            Which EndpointMapping is used depends on your annotations/configuration annotation-driven registers several.

            Instead of relying on the payload you want to use a soap-action, ws-addressing or other means. I suggest a read of the spring webservices reference guide on how to express mappings.

            Comment


            • #7
              Hi Maarten,
              I have decided to give the SoapAction a try.

              I have added the annotations on my methods

              Code:
                      @SoapAction(value="method2")
              	@ResponsePayload
              	@Transactional(readOnly=true)
              	public SearchCustomerResponse method2(@RequestPayload Element customerSearchOptions) 
              		throws JDOMException, JAXBException{

              However, when the WSDL is generated I find that the SoapAction element shows to be empty

              Code:
                <wsdl:binding name="CustomerSearchServicePortSoap11" type="tns:CustomerSearchServicePort">
                  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
                  <wsdl:operation name="CustomerSearch">
                    <soap:operation soapAction=""/>
                    <wsdl:input name="CustomerSearchRequest">
                      <soap:body use="literal"/>
                    </wsdl:input>
                  </wsdl:operation>
                </wsdl:binding>
              Is this the expected behaviour? Or should my two methods have been set somewhere.

              p.s : I am going through the reference but can't find sufficient information regarding this part.

              regards
              Kris

              Comment


              • #8
                unique request per handling method

                I have finally decided to get it to work with @PayloadRoot and by using specific names for the requests for each method

                Code:
                 <xs:element name="method1Request">
                        <xs:complexType>
                            <xs:all>
                                <xs:element minOccurs="0" name="cusId" nillable="true" type="xs:string"/>
                            </xs:all>
                        </xs:complexType>
                    </xs:element>
                  
                     <xs:element name="method2Request">
                        <xs:complexType>
                            <xs:all>
                                <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
                            </xs:all>
                        </xs:complexType>
                    </xs:element>
                But I will definitely investigate the SoapAction as well...Feel free to comment on the approach

                Comment


                • #9
                  Kris,
                  Did you figure it out with @SoapAction or other annotation way? I am also interested in this minor but useful improvement.

                  Thanks,
                  Xuebin

                  Comment

                  Working...
                  X