116100283 Handling Attachments in Apache Axis 1.1 in MIME encoded format Introduction This document is the detailed design specification for support of attachments in Web services. Here the Client will send N number of files as attachments to the Server, by just calling the Web service, which is already deployed. Scope The scope of this document include: 1) Changes needed at the client and server side to handle attachments. 2) Adding attachments to the SOAPMessage in MIME encoded format at the client end. 3) Setting the Filenames in the Header of the SOAPMessage at the client end. 4) Retrieving the attachments at the Server side and saving it onto the file system. It does NOT include the handling of attachments in INLINE form where the attachments are send as a part of the SOAPBody. Here we deal with sending attachments as multiparts which follow the SOAPBody in a MIME encoded SOAPMessage. Assumptions The Web service is already deployed and client is also ready. Note: Please add activation.jar and mail.jar to the classpath Design 1) Client Side A DataHandler (javax.activation.DataHandler) object is instantiated to add the File that is to be send as attachment. DataHandler dHandler = new DataHandler (new FileDataSource ("abc.txt")); Now we have a datahandler that contains the attachment file. Create an object of Client stub and set its property as shown below. TestService service = new TestServiceLocator (); TestSoapBindingStub stub = new TestSoapBindingStub (url, service); This method call will the set the property ATTACHMENT_ENCAPSULATION_FORMAT with ATTACHMENT_ENCAPSULATION_FORMAT_MIME. It means that the call to the webservice method is accompanied by an attachment in MIME encoded format. stub._setProperty(Call.ATTACHMENT_ENCAPSULATION_FORMAT,Call.ATTACHMENT_ ENCAPSULATION_FORMAT_MIME); Dhanush Gopinath Page 1 2/12/2016 116100283 Now add the attachment to the stub object. This line of code adds the DataHandler object to the stub now the SOAPMessage generated will have a part, which contain the attachment file. stub.addAttachment(dHandler); Note: One can set the filenames of the attached files in the Header of the SOAPMessage by the below mentioned code. This is useful when you need to save the file at the server side in the same name, as it is send. stub.setHeader("Header","fileName1",dHandler.getDataSource().getName()); Call the web service method by using the Stub. stub.webserviceMethod(Param1,param2,..paramN); 2) Server Side At the server side the method should extract the attachments and store it to the file system. The attachment that is send is in MIME encoded format and the each of them have different Content Types like “text/plain”, “text/xml”,”image/gif”,”image/jpeg”,”application/octet-stream” etc. To retrieve the attachment from the SOAPMessage we need to have the SOAPMessage and here the type of SOAPMessage is Request Message. A Request Message can be obtained at the server side by instantiating the current MessageContext and getting the Request message from the MessageContext. MessageContext msgContext = MessageContext.getCurrentContext(); Message reqMsg = msgContext.getRequestMessage(); Then you can get the attachments from the request message on to an Iterator. Attachments messageAttachments = reqMsg.getAttachmentsImpl(); Iterator itrAttachs = messageAttachments.getAttachments().iterator(); Now retrieve each attachment part from the set of attachments in the iterator by iterating through. AttachmentPart attachment = (AttachmentPart) itrAttachs.next(); This attachment object will contain the content of each file attached. We need to know the content type of the attachment since the content of attachment will be of different types and the method getContent() of Class AttachmentPart returns different objects according to the ContentType. Eg: - It returns InputStream when ContentType is “application/octet-stream” and String when it is “text/plain”. So find the ContentType and get the content accordingly and write to the file system accordingly. String type = attachment.getContentType(); Dhanush Gopinath Page 2 2/12/2016 116100283 Object obj= attachment.getContent(); Sample SOAPMessage This message contains the original SOAPBody along with two attachment files in Parts. ------=_Part_0_5683514.1085485078845 Content-Type: text/xml; charset=UTF-8 Content-Transfer-Encoding: binary Content-Id: <4CF680E9FCA3B7E4444DAC3A6AEE5159> <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:fileName1 soapenv:mustUnderstand="0" xsi:type="xsd:string" xmlns:ns1="Header">space.txt</ns1:fileName1> <ns2:fileName2 soapenv:mustUnderstand="0" xsi:type="xsd:string" xmlns:ns2="Header">dhanush.txt</ns2:fileName2> </soapenv:Header> <soapenv:Body> <ns3:putMessage soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns3="urn:webservices.oexgateway.bt.com"> <in0 href="#id0"/> </ns3:putMessage> <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns4:OAGMessage" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns4="urn:webservices.oexgateway.bt.com"> <aqMessageID xsi:type="xsd:string" xsi:nil="true"/> <docRefNum xsi:type="xsd:string" xsi:nil="true"/> <documentID xsi:type="xsd:string" xsi:nil="true"/> <messagePayload xsi:type="xsd:string" xsi:nil="true"/> <messageStatus xsi:type="xsd:int">0</messageStatus> <oagDocType xsi:type="ns4:OAGDocType" xsi:nil="true"/> <partySiteID xsi:type="xsd:string" xsi:nil="true"/> <recipientID xsi:type="xsd:string" xsi:nil="true"/> <senderID xsi:type="xsd:string" xsi:nil="true"/> </multiRef> </soapenv:Body> </soapenv:Envelope> ------=_Part_0_5683514.1085485078845 Content-Type: text/plain Content-Transfer-Encoding: binary Content-Id: <EBC9779B02118302509F3FCE8A18849B> dsgfdsfdgfdgfds fdgdfgfdgsdf dfgdfgsdfgfds fhgsdfgfdgf Hello all how r u guys ?? This is a text file send from AXIS thru attchs ------=_Part_0_5683514.1085485078845 Dhanush Gopinath Page 3 2/12/2016 116100283 Content-Type: text/plain Content-Transfer-Encoding: binary Content-Id: <6315E58F0CE8C80D03CD8D2968F00BF4> package org.bt.oexgateway.webservices; import import import import import import import org.apache.axis.AxisFault; org.apache.axis.Message; org.apache.axis.MessageContext; org.apache.axis.encoding.Base64; org.apache.axis.handlers.BasicHandler; org.apache.axis.message.MessageElement; org.apache.axis.utils.JavaUtils; import import import import org.apache.axis.message.SOAPEnvelope; org.apache.axis.utils.XMLUtils; java.io.*; javax.naming.InitialContext; public class AttachmentHandler extends BasicHandler { public void invoke(MessageContext msgContext) throws AxisFault { Message reqMsg = msgContext.getRequestMessage(); Message respMsg = msgContext.getResponseMessage(); Attachments messageAttachments = reqMsg.getAttachmentsImpl(); int attachmentCount= messageAttachments.getAttachmentCount(); AttachmentPart attachments[] = new AttachmentPart[attachmentCount]; Iterator it = messageAttachments.getAttachments().iterator(); int count = 0; while (it.hasNext()) { AttachmentPart part = (AttachmentPart) it.next(); attachments[count++] = part; } try { respMsg.writeTo(new FileOutputStream("D:\\mime_ws\\attachs\\soaprespMesg.txt")); reqMsg.writeTo(new FileOutputStream("D:\\mime_ws\\attachs\\soapreqMesg.txt")); } catch(Exception e) { System.out.println("Exception in Writing Soap Message "+ e); } } } ------=_Part_0_5683514.1085485078845— Dhanush Gopinath Page 4 2/12/2016 116100283 Reference: Attached document in http://www.mail-archive.com/axis-user@xml.apache.org/msg08732.html Document Name: Fear of Attachments.pdf By: Steve Loughran Quote “There is no WSDL. Or to be precise, attachments aren’t in the signature that WSDL knows about” - Steve Loughran Dhanush Gopinath Page 5 2/12/2016