Child pages
  • Web Services-Sending Large Data
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

Kristoff Cossement

Soap with mime attachments was indeed the way to go.

Remark: this only works with java 1.4.2_09 (I did not get it working with java 1.5.x)

For those who are interested I included some sample code on how to exchange large binary data between a java client and and webobjects server without taking all data in memory.
You also need the java mail and java activation framework from sun.

Client.java

 import javax.xml.soap.SOAPConnectionFactory;
 import javax.xml.soap.*;
 import javax.xml.transform.stream.*;
 import javax.xml.transform.*;
 import java.io.*;
 import org.apache.axis.attachments.AttachmentPart;
 import org.apache.axis.message.*;
 import javax.activation.DataHandler;
 import javax.activation.FileDataSource;
 import javax.xml.soap.SOAPElement;
 import java.util.*;
 import javax.mail.*;

 public class Client {

   public static File resize(String sPath)
   {
     File file = new File(sPath);


     String endPoint = "http://localhost:55555/cgi-bin/WebObjects/project.woa/ws/FileUpload";
     try{
       SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
       SOAPMessage message = (javax.xml.soap.SOAPMessage)MessageFactory.newInstance().createMessage();
       SOAPPart part = message.getSOAPPart();
       SOAPEnvelope envelope = (org.apache.axis.message.SOAPEnvelope)part.getEnvelope();
       SOAPBody body = (org.apache.axis.message.SOAPBody)envelope.getBody();
       SOAPBodyElement operation = (org.apache.axis.message.SOAPBodyElement)body.addBodyElement(
           envelope.createName("upload",
             "ns",
             "http://localhost:55555/cgi-bin/WebObjects/project.woa/ws/FileUpload"));
       operation.setEncodingStyle("http://schemas.xmlsoaporg/soap/encoding/");

       DataHandler dh = new DataHandler(new FileDataSource(file));
       AttachmentPart attachment = (org.apache.axis.attachments.AttachmentPart)message.createAttachmentPart(dh);
       SOAPElement filename = operation.addChildElement("filename","");
       SOAPElement source = operation.addChildElement("source","");
       message.addAttachmentPart(attachment);
       filename.addTextNode(file.getName());
       source.addTextNode(attachment.getContentId());

       SOAPMessage result = connection.call(message,endPoint);
       System.out.println(result);
       part = result.getSOAPPart();
       envelope = (org.apache.axis.message.SOAPEnvelope)part.getEnvelope();
       body = (org.apache.axis.message.SOAPBody)envelope.getBody();

       if(!body.hasFault())
       {
         System.out.println("answer : "+body);

       }
     }
     catch(Exception e)
     {
       e.printStackTrace();
     }
     return null;
   }

   public static void main(String[] args) {

     try {

       resize(args[0]);

     }
     catch (Exception e) {
       System.out.println(e.getMessage());
     }
   }
 }
Webobjects Application .java

override dispatchRequest

  public WOResponse dispatchRequest(WORequest request)
 {
   WOResponse result = null;
   String sURI = request.uri();
   NSLog.debug.appendln("Accessing " + sURI);

   Pattern p = Pattern.compile("/ws/FileUpload");
   Matcher m = p.matcher(sURI);
   if(m.find())
   {
     String sContType = request.headerForKey("content-type");
     p = Pattern.compile("multipart/related");
     m = p.matcher(sContType);
     if(m.find())
     {
       result = Dispatcher.handleFileUpload(request);
     }
     else
     {
       result = super.dispatchRequest(request);
     }
   }
   else
   {
     result = super.dispatchRequest(request);
   }

   return result;

 }
Dispatcher.java
  //
 // Dispatcher.java
 // project
 //
 // Created by admin on 5/5/06.
 // Copyright 2006 __MyCompanyName__. All rights reserved.
 //
 import com.webobjects.foundation.*;
 import com.webobjects.appserver.*;
 import com.webobjects.eocontrol.*;

 import java.io.*;
 import java.util.regex.*;
 import org.w3c.dom.*;
 import javax.xml.transform.*;
 import javax.xml.transform.stream.*;
 import javax.xml.transform.dom.*;
 import javax.xml.parsers.*;
 import org.apache.axis.attachments.*;


 public class Dispatcher {

   public static WOResponse handleFileUpload(WORequest request)
   {
     String sContType = request.headerForKey("content-type");
     String sSoapXml = "";
     InputStream requestStream = request.contentInputStream();

     String sTempDir = System.getProperty("java.io.tmpdir");
     String timestamp =(new Long(System.currentTimeMillis())).toString();
     File fTempFile = new File(sTempDir+"/"+timestamp);
     File fSavedFile = new File(sTempDir+"/"+timestamp+".out");

     try
     {
       BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(fTempFile));
       byte[] buffer = new byte[32 * 1024];
       int bytesRead = 0;
       while ((bytesRead = requestStream.read(buffer)) != -1)
       {
         fOut.write(buffer, 0, bytesRead);
       }
       fOut.close();
     }
     catch (Exception e)
     {
       NSLog.debug.appendln(e.getMessage());
     }

     try
     {
       InputStream iStream = new FileInputStream(fTempFile);

       MultiPartRelatedInputStream mis = new MultiPartRelatedInputStream(sContType,iStream);
       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
       Document doc = factory.newDocumentBuilder().parse(mis);
       sSoapXml = toString(doc);
       NSLog.debug.appendln("SOAP Envelope: " + sSoapXml);
       mis.close();
       iStream.close();

       Node nEnvelope = getNamedChildNode(doc,"Envelope");
       if(null != nEnvelope)
       {
         Node nBody = getNamedChildNode(nEnvelope,"Body");
         if(null != nBody)
         {
           NSArray nSubNodes = getElementChildNodes(nBody);
           if((null != nSubNodes) && (nSubNodes.count() > 0))
           {
             Node nFileUpload = (Node)nSubNodes.get(0);
             nSubNodes = getElementChildNodes(nFileUpload);
             if((null != nSubNodes) && (nSubNodes.count() > 1))
             {
               Node nFileName = (Node)nSubNodes.get(0);
               Node nData = (Node)nSubNodes.get(1);

               String sFileName = getTextFromNode(nFileName);
               String sFileMimeID = getTextFromNode(nData);

               fSavedFile = new File(sTempDir+"/"+sFileName);

               Pattern pattern = Pattern.compile("(boundary=\".+?\")");
               Matcher match = pattern.matcher(sContType);
               if(match.find())
               {
                 String boundary= match.group(1);
                 String sSubContentType = "multipart/related; type=\"text/xml\"; start=\"<"+sFileMimeID+">\";   "+boundary;
                 iStream = new FileInputStream(fTempFile);
                 mis = new MultiPartRelatedInputStream(sSubContentType,iStream);
                 try
                 {
                   BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(fSavedFile));
                   byte[] buffer = new byte[32 * 1024];
                   int bytesRead = 0;
                   while ((bytesRead = mis.read(buffer)) != -1)
                   {
                     fOut.write(buffer, 0, bytesRead);
                   }
                   mis.close();
                   fOut.close();
                 }
                 catch (Exception e)
                 {
                   System.out.println(e.getMessage());
                   //throw new IOException(me + " failed, got: " + e.toString());
                 }
               }
             }
           }
         }
       }
     }
     catch(Exception e)
     {
       e.printStackTrace();
     }


     WOResponse result = new WOResponse();
     result.setContent( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
         "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoaporg/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"+
         "<soapenv:Body>\n"+
         "<ns:uploadResponse soapenv:encodingStyle=\"http://schemas.xmlsoaporg/soap/encoding/\" xmlns:ns=\"http://localhost:55555/cgi-bin/WebObjects/project.woa/ws/FileUpload\">\n"+
         "<ns:uploadReturn xsi:type=\"xsd:boolean\">true</ns:uploadReturn>\n"+
         "</ns:uploadResponse>\n"+
         "</soapenv:Body>\n"+
         "</soapenv:Envelope>");


     result.setHeader("text/xml; charset=utf-8","content-type");


     return result;

   }


   static public String toString(Document document) {
     String result = null;

     if (document != null) {
       StringWriter strWtr = new StringWriter();
       StreamResult strResult = new StreamResult(strWtr);
       TransformerFactory tfac = TransformerFactory.newInstance();
       try {
         Transformer t = tfac.newTransformer();
         t.setOutputProperty(OutputKeys.ENCODING, "utf-8");
         t.setOutputProperty(OutputKeys.INDENT, "yes");
         t.setOutputProperty(OutputKeys.METHOD, "xml"); //xml, html, text
         t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
         t.transform(new DOMSource(document.getDocumentElement()), strResult);
       } catch (Exception e) {
         System.err.println("XML.toString(Document): " + e);
       }
       result = strResult.getWriter().toString();
     }

     return result;
   }

   static public Node getNamedChildNode(Node n, String sChildNodeName)
   {

     NodeList nl = n.getChildNodes();

     for(int i=0;i<nl.getLength();i++)
     {
       Node s = nl.item(i);
       String sChild = s.getNodeName();
       if(sChildNodeName.equalsIgnoreCase(sChild) || sChild.endsWith(":"+sChildNodeName))
       {
         NSLog.debug.appendln("childnode = " + s.getNodeName());
         return s;
       }
     }

     return null;

   }
   static public NSArray getElementChildNodes(Node n)
   {
     NSMutableArray elements = new NSMutableArray();
     NodeList nl = n.getChildNodes();

     for(int i=0;i<nl.getLength();i++)
     {
       Node s = nl.item(i);
       if(s.getNodeType() == Node.ELEMENT_NODE)
       {
         NSLog.debug.appendln("childnode = " + s.getNodeName());
         elements.addObject(s);
       }
     }

     return elements;
   }
   static public String getTextFromNode(Node n)
   {
     String text = "";

     NodeList nl = n.getChildNodes();

     for(int i=0;i<nl.getLength();i++)
     {
       Node s = nl.item(i);
       if(s.getNodeType() == Node.TEXT_NODE)
       {
         return s.getNodeValue();
       }
     }
     return text;
   }
 }
  • No labels