Thanks for the contribution!

John Walker wrote:
I have a spot of code I would like to contribute to the group.  This
class I developed can be used to detach or attach any file sent over
web services.
This class is intended for use on the server side, and will need just
a little massaging to work in your environment.

It took me several painstaking hours to get AXIS to send an attachment
to a requesting .NET client, and for .NET to send an attachment to a
listening AXIS server.  With the help of the Steve Loughran article
"Fear of Attachments", and not a little of his code (thanks Steve!), I
was able to get .NET clients to utilize files stored on my AXIS web
server.

Please forgive the Exception handling.

To read Steve Loughran's article I referred to, ref:
http://www.mail-archive.com/axis-user@xml.apache.org/msg08732.html

 - John Walker
  

package ws.attachments; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Iterator; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.xml.soap.AttachmentPart; import org.apache.axis.AxisFault; import org.apache.axis.Message; import org.apache.axis.MessageContext; import org.apache.axis.attachments.Attachments; import org.apache.axis.attachments.AttachmentsImpl; import org.apache.log4j.Logger; /** * This class can be used from within any AXIS web service method * * @author jwalker */ public class AttachmentTrundler { private static final Logger _logger = Logger.getLogger(AttachmentTrundler.class); public AttachmentTrundler() { } /** * Attaches the file to the outgoing response message as DIME attachment. * This attachment should be consumable by all .NET web service * clients. The clients we are using are auto-generated proxy classes * that have no knowledge of the attachment coming. The WSDL will not * contain this information. * * @param fileName The full name of the file on the local filesystem to * send to the client requesting file attachment * @return true, indicating attachment was successful. * * @throws AttachmentException */ public boolean attachFile(File file) throws AttachmentException { try { MessageContext msgContext = MessageContext.getCurrentContext(); Message resMsg = msgContext.getResponseMessage(); //Get the file from the filesystem FileDataSource fileDS = new FileDataSource(file); DataHandler handler = new DataHandler(fileDS); //Create the attachment as a DIME attachment AttachmentPart attachment = resMsg.createAttachmentPart(); resMsg.getAttachmentsImpl().setSendType(AttachmentsImpl.SEND_TYPE_DIME); attachment.setDataHandler(handler); //You can set the content type to be anything you wish. All my files are zips attachment.setContentType("zip"); resMsg.addAttachmentPart(attachment); }catch (Exception e) { //I know some will argue about the wisdom of catching Exception, and then // throwing AttachmentException, and they would probably be right. _logger.error("attachFile(File file = " + file + ")", e); throw new AttachmentException("There was a problem attaching the file to the web service call", e); } return true; } /** * This method receives the DIME encoded attachment from the client and * saves it on the server. * * @param filename as the name to save the file on the server * @return a java.io.File that represents the object on the file system * * @throws AttachmentException This exception is thrown if anything * goes wrong within the detachment process. */ public File detachFile(String filename) throws AttachmentException { InputStream is = null; FileOutputStream os = null; File file = null; int totalAttachments ; try { //Get all the attachments AttachmentPart[] attachments = getMessageAttachments(); /* * getMessageAttachments() as provided by Steve Loughran in his mail * to axis-user group * http://www.mail-archive.com/axis-user@xml.apache.org/msg08732.html */ //Put the logic in a loop for totalAttachments for multiple // attachments. totalAttachments = attachments.length; _logger.debug("saveFile(String filename = " + filename + ") - " + "Total Attachments Received Are: "+ totalAttachments); if (totalAttachments != 1) { throw new AttachmentException("Too many attachments sent [" + attachments.length + "] Please limit to 1"); } //Extract the first attachment. (Since in this case we have only one attachment sent) DataHandler dh = attachments[0].getDataHandler(); //Extract the file name of the first attachment. String name = filename; _logger.debug("saveFile(String filename = " + filename + ") - File received on server is: " + name); //Get the streams to file and from attachment, then stream to disk is = dh.getInputStream(); file = new File(name); os = new FileOutputStream(file); this.writeBuffersAndClose(is, os); } catch (Exception e) { _logger.error("detachFile(String filename = " + filename + ")", e); throw new AttachmentException(e); } if(file!= null) return file; else throw new AttachmentException("The attachment was not saved"); } /** * extract attachments from the current request * * @return a list of attachmentparts or an empty array for no attachments * support in this axis buid/runtime */ private AttachmentPart[] getMessageAttachments() throws AxisFault { /* * Reusing the method implementation for AttachmentPart[] * getMessageAttachments() as provided by Steve Loughran in his mail to * axis-user group * http://www.mail-archive.com/axis-user@xml.apache.org/msg08732.html */ MessageContext msgContext = MessageContext.getCurrentContext(); Message reqMsg = msgContext.getRequestMessage(); Attachments messageAttachments = reqMsg.getAttachmentsImpl(); if (null == messageAttachments) { System.out.println("no attachment support"); return new AttachmentPart[0]; } 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; } return attachments; } /** * Simple method for writing one stream from another. * * @param is * @param os * @throws IOException */ private void writeBuffersAndClose(InputStream is, OutputStream os) throws IOException { int i = 0; byte [] buffer = new byte[1024]; while (i != -1) { i = is.read(buffer, 0, buffer.length); if(i > 0) os.write(buffer, 0, buffer.length); } is.close(); os.close(); } }

Reply via email to