Well I'm only sending one attachment and I guess it should be the same if you agree (document) your web service which attachment you will find in which order. I guess you can add several.
Well it's true as well that I don't put the attachment as a parameter of the web service method, but the name of the file yes. I don't know if that really work in RPC style (I never try it out, I was assuming this will be send anyway as part of the normal SOAP body, but I'm maybe wrong).
Anyway, here what I'm doing (still assuming I'm sending a file) (BTW this works with java clients as well):
On the server side I'm doing the following to accept attachments from the client side:
// getting the request Message
org.apache.axis.MessageContext msgContext = org.apache.axis.MessageContext.getCurrentContext();
org.apache.axis.Message reqMsg = msgContext.getRequestMessage();
reqMsg.getAttachmentsImpl().setSendType(org.apache.axis.attachments.Attachments.SEND_TYPE_DIME);
// finding Attachements
java.util.Iterator iterAttachs = reqMsg.getAttachments();
// looping on attachments
while (iterAttachs.hasNext()){
org.apache.axis.attachments.AttachmentPart attchment = (org.apache.axis.attachments.AttachmentPart)iterAttachs.next();
javax.activation.DataHandler dh = attchment.getDataHandler();
org.apache.axis.attachments.ManagedMemoryDataSource mmds = (org.apache.axis.attachments.ManagedMemoryDataSource)dh.getDataSource();
if (mmds!=null){
// getting the stream of the attachment
java.io.InputStream is = mmds.getInputStream();
// writing the stream to a file
java.io.File attachedFile = new java.io.File("<name of the file to be stored on the server side>");
java.io.BufferedOutputStream bos = new java.io.BufferedOutputStream(new java.io.FileOutputStream(attachedFile));
int size;
byte[] buf = new byte[1024];
while ((size = is.read(buf)) > -1) {
bos.write(buf, 0, size);
}
bos.flush();
bos.close();
}
// maybe break the loop if attachedFile!=null if needed
}
And on the .NET client side to send the attachment:
FileInfo fileInfo = new FileInfo("<File name to send>"); if (fileInfo.Exists) { FileStream fs = fileInfo.OpenRead();
SoapContext reqContest = service.RequestSoapContext; DimeAttachmentCollection attachements = reqContest.Attachments;
attachements.Add(new DimeAttachment("application/octet-stream",TypeFormatEnum.Unknown,fs));
// call the ws method String ret = service.<the ws method that accept attachements>; reqContest.Attachments.Clear(); fs.Close(); }
Cheers, Patrick.
Praveen Peddi wrote:
I should Thank you all for such an amazing response. I think some responses definitely help me. But My problem is slightly different.
First thing, Base64 option is ruled since we implemented it before and then moved to DataHandler. The size of the content is surely an issue. We do use large attachements.
Thanks to Patrick Houbaux for such a detailed example. It was good. But I use attachemnts as input method arguments. Following is the method signature:
public String createOrUpdateContentObjectWithAttachments(String sessionID,
String containerID, String xmlString, String customerID, String contentID, DataHandler source, String sourceFileName,
DataHandler thumb, String thumbFileName);
So its not just one attachment. Th user sends the source stream, sourceFileName, thumb stream and thumb file name. So I have to associate each attahment with the file name. Its not like I am getting the list of attachments and I save it randomly. I have to know what attachment is what (whether its a source content or thumb content). Also if the attachments' info is not part of the method, it will be really ahard and confusing for the user to use that method. Well if this is the only efficient way, I have to adopt this method.
Patrick, Is your sample same even for input arguments? I mean you send attachments as part of request?
Thanks
Praveen
----- Original Message -----
From: "ANDREW MICONE" <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>
To: <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>
Sent: Friday, January 07, 2005 3:13 PM
Subject: RE: Best way to send attachments
Here's an example of a WSDL snippet that is consumed by both .NET and Axis that handles attachments and interoperates between the two. This is from a service in production:
<complexType name="NodeDocument"> <sequence> <element name="name" nillable="true" type="xsd:string"/> <element name="type" nillable="true" type="xsd:string"/> <element name="content" nillable="true" type="xsd:anyType"/> </sequence> </complexType> <complexType name="ArrayofDoc"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:NodeDocument[]"/> </restriction> </complexContent> </complexType>
BTW, I didn't write it, I just implemented it. -- Andy
>>> [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> 01/07/05 12:26PM >>> I don't believe there is a way to define this in wsdl so that both .Net and Java(axis) can consume the wsdl. Someone please correct me if I am wrong. My clients just have to understand that certain methods have filles attached. I also allow them to set a request parameter do define whether the attachment should be set to Dime or Mime encoding (the service is Axis).
Raul
-----Original Message----- From: BLIS Webmaster (Patrick Houbaux) [mailto:[EMAIL PROTECTED] Sent: Friday, January 07, 2005 1:12 PM To: [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> Subject: Re: Best way to send attachments
I have no problem sending attachements to .NET client.
I have a RPC web service (I guess it works for other web service style), and here is the methodologie:
Let's assume you have a web service supposed to send some attachments, the idea is to add the attachment to the SOAP message before the web service method returns on the server side (please note the following is using AXIS 1.1, but it is almost the same with the latest version of AXIS, the AXIS API has changed a bit).
1- get the response message from the message context: //... org.apache.axis.MessageContext msgContext= org.apache.axis.MessageContext.getCurrentContext(); org.apache.axis.Message rspMsg= msgContext.getResponseMessage();
2 - Set the attachment type to be sent as DIME
rspMsg.getAttachmentsImpl().setSendType(org.apache.axis.attachments.Atta chments.SEND_TYPE_DIME);
3- Let's assume you want to send a file
java.io.File fileToAddAsAttachment = new java.io.File("<the path to your file>");
4- Add the file to attachment of the response message
javax.activation.DataHandler dh=new javax.activation.DataHandler(new javax.activation.FileDataSource(fileToAddAsAttachment)); org.apache.axis.attachments.AttachmentPart part = new org.apache.axis.attachments.AttachmentPart(dh); rspMsg.addAttachmentPart(part);
5- Return your method
The drawback with that is I haven't figured out how to declare (with java2wsdl) the attachment in the WSDL so you have to document your web service or inform your clients they have to expect some attachments when they call your method.
On the .NET client side, the method is the following:
1- Call the web service method
2- Just after the previous call returned, get the SOAP Response message context SoapContext rspContext = service.ResponseSoapContext;
3- Get the DIME attachements, loop on them and write in a file what you find there: DimeAttachmentCollection attachments = rspContext.Attachments; for (int i=0; i<attachments.Count; i++) { Stream str = attachments[i].Stream; FileStream fs = new FileStream("<the file name where you want to save the attachment>",FileMode.Create,FileAccess.Write); ((MemoryStream)str).WriteTo(fs); str.Close(); fs.Close(); }
That's all, that works perfectly for me ... hope it helps.
Cheers, Patrick.
Vy Ho wrote: > All of the reples make no sense whatsover to me. > > The original poster makes a very clear question that how to send > attachments using soap way that works with many environments. For > example, Axis and .Net. > > To rephrase this, I would say how to create a Wsdl that works with > both axis and .net. Currently, using the DataHandler in the wsdl (or > generating the wsdl from java code with DataHandler) would not work > with other environment. I haven't tried this, but looking at the > definition of DataHandler (package name), and its namespace in the > wsdl, you can tell it comes from apache, not some Soap standard, > unless Apache is the official standard used for attachment. > > It's funny to read a bunch of replies that have little answer value to
> the original question.