3

I am really struggling getting Spring-WS to return a response with attachments. I have managed to get an MTOM version to work but this has some pre-requisites on the client as i believe that the client has to be MTOM enabled as well (please correct me if this is not correct).

What i am trying to do now is to use the standard SOAP with attachment implementation using SAAJ and Spring-WS.

To do this i implemented an endpoint that just attaches an image from the local filesystem to the response.

@Endpoint
public class TestEndPoint {

private SaajSoapMessageFactory saajMessageFactory;

@PayloadRoot(namespace="http://ws.mypackage.com", localPart="downloadMessageRequestSaaj")
    @ResponsePayload
    public JAXBElement<DownloadResponseSaajType> invoke(@RequestPayload DownloadMessageRequestSaaj req, MessageContext context ) throws Exception  {

        DownloadResponseSaajType response = new DownloadResponseSaajType();
        DownloadResponseSaajType.PayLoad payload = new DownloadResponseSaajType.PayLoad();  

        DataHandler handler = new javax.activation.DataHandler(new FileDataSource("c:\\temp\\maven-feather.png"));

            SaajSoapMessage message = saajMessageFactory.createWebServiceMessage();
            message.addAttachment("picture", handler);

            context.setResponse(message);

            payload.setMessagePayLoad(handler);

            return objectFactory.createDownloadMessageResponseSaaj(response);  

    }

    public void setSaajMessageFactory(SaajSoapMessageFactory saajMessageFactory){
        this.saajMessageFactory = saajMessageFactory;
    }

    public SaajSoapMessageFactory getSaajMessageFactory(){
        return saajMessageFactory;
    }
}

The Saaj properties are depency injected as shown below:


<sws:annotation-driven/>

<bean id="soapMessageFactory" class="javax.xml.soap.MessageFactory" factory-method="newInstance" />
<bean id="saajMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
        <constructor-arg ref="soapMessageFactory" />
</bean>

<bean id="myService" class="com.mypackage.TestEndPoint">
    <property name="saajMessageFactory" ref="saajMessageFactory" />
</bean>

When i try to call the above service i get the following error:

<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">No adapter for endpoint [public javax.xml.bind.JAXBElement&lt;com.mypackage.ws.DownloadResponseSaajType> com.mypackage.TestEndPoint.invoke(com.mypackage.ws.DownloadMessageRequestSaaj,org.springframework.ws.context.MessageContext) throws java.lang.Exception]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?</faultstring>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Edit 13th July

I noticed today that i change the method signature to remove the MessageContext parameters as shown below then i dont get that error:

public JAXBElement<DownloadResponseSaajType> invoke(@RequestPayload DownloadMessageRequestSaaj req)

The problem however is that i need to access the MessageContext to be able to add the attachment. Could be that maybe my configuration is wrong somewhere?

ziggy
  • 15,677
  • 67
  • 194
  • 287
  • This was driving me mad the other day but with a different parameter set. Does it give the error if you remove the "@RequestPayload DownloadMessageRequestSaaj req," Part of the payload method parameter? If so try a different version of that class. I was trying to do it with a org.jdom.element, but that kept giving the error. I switched to jdom2 and then it suddenly worked. I guess theres some incompatibility with the older jdom - perhaps theres a similar issue here. – Davos555 Jul 13 '12 at 13:09
  • I tried changing the method parameter to "public JAXBElement invoke(MessageContext context )" but it still gives the same error. – ziggy Jul 13 '12 at 16:49
  • Just noticed that the error does disappear if i remove the MessageContextParameter but i need that to be able to add the attachment to the response. – ziggy Jul 13 '12 at 17:06
  • Following [this answer](http://stackoverflow.com/a/6446238/983430) worked for me. – Amos M. Carpenter Nov 10 '14 at 06:10

1 Answers1

1

I believe in either case your client will need to be aware of the attachment so I would recommend sticking with mtom (as it is becoming the standard)

check which version of spring-ws you are using and which maven group-id you are using. i was getting the same error because this feature was recently added (I think?).

try this entry and remove any other spring-ws imports your making

    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
        <version>2.0.2.RELEASE</version>
    </dependency>
Shaun Stone
  • 626
  • 1
  • 5
  • 19
  • I am using version 2.0.3.RELEASE. Everything else is exactly the same and i dont have any other spring-ws imports. – ziggy Jul 14 '12 at 12:58
  • what is your MethodEndpointAdapter that you have configured? i.e. org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter. also if you set it at trace you will see the `org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter.supports(O bject endpoint)` method being called which decides which adapter will handle that method type. your MethodEndpointAdapter will need to have the MessageContextMethodArgumentResolver added as one of the methodArgumentResolvers. – Shaun Stone Jul 16 '12 at 18:21
  • (the DefaultMethodEndpointAdapter has this configured by default) – Shaun Stone Jul 16 '12 at 18:37
  • Thanks Shaun i have now sorted it. The problem was because the saajMessageFactory was not being Autowired correctly. – ziggy Jul 17 '12 at 08:28