[SWS-864] Intercept request with a payload that have not been defined in a EndpointMapping Created: 20/Feb/14  Updated: 20/Mar/14  Resolved: 25/Feb/14

Status: Resolved
Project: Spring Web Services
Component/s: Core
Affects Version/s: 2.1.4
Fix Version/s: 2.2.RC1

Type: Improvement Priority: Minor
Reporter: Thomas Champagne Assignee: Arjen Poutsma
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


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



 Comments   
Comment by Arjen Poutsma [ 25/Feb/14 ]

Fixed by introducing a @PayloadRoots annotation. Nice idea!

Generated at Tue Dec 12 10:05:23 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.