Uploaded image for project: 'Spring Web Services'
  1. Spring Web Services
  2. SWS-864

Intercept request with a payload that have not been defined in a EndpointMapping

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.1.4
    • Fix Version/s: 2.2.RC1
    • Component/s: Core
    • Labels:
      None

      Description

      With the current EndpointInterceptor implementation, it is not possible to handle a request with a payload that have not been defined in a EndpointMapping. The handleRequest method of EndpointInterceptor is called after the MessageDispather get an endpoint based on the payload request. If no endpoint is found, the MessageDispatcher throws NoEndpointFoundException (and generate with servlet a 404 error).
      So, it's not possible to use the PayloadTransformingInterceptor for changing the namespace or name of a payload element because this QName may not be defined in a EndpointMapping.

      For example, with this payload :

      @PayloadRoot(localPart = "TestRequest", namespace = "http://test.com/v2.0")

      and I want to transform request from namespace http://test.com/v1.0 to http://test.com/v2.0, so I define this interceptor :

      <sws:interceptors>
        <sws:payloadRoot namespaceUri="http://test.com/v1.0">
          <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadTransformingInterceptor">
            <property name="requestXslt" value="v1tov2.xslt" />
          </bean>
        </sws:payloadRoot>
      </sws:interceptors>

      But if I call with this request :

      <TestRequest xmlns="http://test.com/v1.0" />

      the MessageDispather throws a "no endpoint found".

      I read the spring-ws code and I found two solution to fix this problem.

      The first solution is to add a new method in EndPointInterceptor interface (or add a new interface) without endpoint parameter (EndpointInvocationChain mappedEndpoint) : handleRequest(MessageContext messageContext).
      And call it before get the endpoint in MessageDispatcher.

      The second solution is to be able to define some @PayloadRoot on a method. But for this, you must create a new annotation to accept some @PayloadRoot. For example, @PayloadRoots. And for example, you could have :

      @PayloadRoots({
        @PayloadRoot(localPart = "TestRequest", namespace = "http://test.com/v1.0"),
        @PayloadRoot(localPart = "TestRequest", namespace = "http://test.com/v2.0")
      })
      public TestResponse test(TestRequest test);

        Activity

        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        Fixed by introducing a @PayloadRoots annotation. Nice idea!

        Show
        arjen.poutsma Arjen Poutsma added a comment - Fixed by introducing a @PayloadRoots annotation. Nice idea!

          People

          • Assignee:
            arjen.poutsma Arjen Poutsma
            Reporter:
            lafeuil Thomas Champagne
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: