10

Basically I want to create a web services client to send a mtom soap message via the proxy method. I have created my service artifacts fine from the web service wsdl. The message is created correctly, however when I enable mtom and add an attachment, the attachment is always sent inline and not in a separate mime part. Its like mtom is enabled but for some reason it decides not to optimize the message and so sends it inline. Running the same code through soapui gives the correct result so I know the service itself will accept it.

Here is my basic code for creating a soap request and sending it. I enable mtomfeature but have also tried doing it with soapBinding.setMTOMEnabled(true); For both methods I have debugged it with ((SOAPBinding) binding).isMTOMEnabled() to check that it is set to being enabled.

// initiate services....

// create service and enable mtom
WebServiceBlah service = new WebServiceBlah(new URL(wsdlURL), SERVICE_NAME);
WebServiceBlahPort port = service.getWebServiceBlahPort(new MTOMFeature(true, 3072));

// load file
File file = new File("/home/mypdf.pdf");
FileInputStream fileinputstream = new FileInputStream(file);
int numberBytes = fileinputstream.available();
byte bytearray[] = new byte[numberBytes];
fileinputstream.read(bytearray);
fileinputstream.close();

// create uploadResult
UploadResult request = new UploadResult();

// create attachment
AttachmentType attachment = new AttachmentType();
attachment.setContentType("application/doc");
attachment.setValue(bytearray);

// create result and add attachment to it
RenderedResult result = new RenderedResult();
result.setResult(attachment);
result.setResultContentType("pdf");
result.setResultName("a pdf file");

// add result to request
request.getResult().add(result);

// send request
port.UploadResults(request);

What I get is my attachment is sent inline as seen below. (captured with wireshark)

POST /blah/ws/ HTTP/1.1
Content-type: multipart/related;start="<rootpart*15c3ee3b-60c7-4726-a52c-8080965e4536@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:15c3ee3b-60c7-4726-a52c-8080965e4536";start-info="text/xml"
Soapaction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.6 in JDK 6
Host: 123.123.123.123
Connection: keep-alive
Content-Length: 12372

--uuid:15c3ee3b-60c7-4726-a52c-8080965e4536    
Content-Id: <rootpart*15c3ee3b-60c7-4726-a52c-8080965e4536@example.jaxws.sun.com>    
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"    
Content-Transfer-Encoding: binary

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header></S:Header>
<S:Body>
<ns2:uploadResult xmlns:xmime="http://www.w3.org/2005/05/xmlmime">
    <renderedResult>
        <result xmime:contentType="application/doc">JVBERi0xLjQKJaqrrK0KNCAwIG9iago8</result>
        <resultContentType>pdf</resultContentType>
        <resultName>a pdf file</resultName>
    </renderedResult>
</ns2:uploadResult>
</S:Body>
</S:Envelope>
--uuid:15c3ee3b-60c7-4726-a52c-8080965e4536

What I want is for the attachment in the result tag to be replaced with the inline tag and the attachment added to the soap message in a different mime part. eg

<result xmime:contentType='application/doc'>
    <inc:Include href="cid:myid3" xmlns:inc='http://www.w3.org/2004/08/xop/include'/>
</result>

And then the following added to the soap message

------=_Part_10_28027205.1314348995670
Content-Type: application/pdf
Content-Transfer-Encoding: binary
Content-ID: cid:myid3
Content-Disposition: attachment; name="mypdf.pdf"
JVBERi0xLjQKJaqrrK0KNCAwIG9iago8
AlexS
  • 650
  • 6
  • 12
  • 3
    Did you solve this? I have the exact same problem. The JAX-WS documentation also says this: `As defined by JAXB 2.0 specification xs:base64Binary and xs:hexBinary mapping to java is byte[]. JAX-WS implementation has set a threshold of 1KB of byte[] size. This threshold can be modified using implementation specific property com.sun.xml.ws.developer.JAXWSProperties.MTOM_THRESHOLD_VALUE in the RequestContext on the client side and in the MessageContext on the server side. You are setting the threshold to 3072 in your code above. Setting this to 0,1,... seems to make no difference. – SteveJ Dec 14 '11 at 05:14

2 Answers2

1

A number of things can affect whether MTOM attachments are actually used.

On the server, firstly the obvious: check that your service implementation has the @MTOM annotation. You can also adjust the threshold value (as SteveJ has already mentioned) from this annotation using the threshold() property.

Sometimes handlers on the server can interfere with whether MTOM attachments are used. Any handler serializes a SOAP message to string or byte array (common for debugging style handlers that write message content to logs) will prevent MTOM attachments from being used. If possible, try disabling your handler chain and seeing if MTOM attachments come through after that.

prunge
  • 22,460
  • 3
  • 73
  • 80
0

I've bump with the same trouble (inline attachments), but it seems just wrong monitoring SOAP message (by MessageHandler): it plays before (in client) and after (at server) of MtomCodec.encode(Packet packet, OutputStream out). Real message could be seen in java code at OutputStream out:

com\sun\xml\ws\jaxws-rt\2.2.10\jaxws-rt-2.2.10-sources.jar!\com\sun\xml\ws\encoding\MtomCodec.java

         for(ByteArrayBuffer bos : mtomAttachments){
             bos.write(out);
         }

Works just with new MTOMFeature(true, 3072) at client side.

Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197