Programming__WebObjects-Web Services-Sending Large Data

Version 1.1 by smmccraw on 2007/07/08 09:46

Kristoff Cossement

Soap with mime attachments was indeed the way to go.

Remark: this only works with java 1.4.209 (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());
}
}
}

WebobjectsApplication.java

overridedispatchRequest

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.iteminformation;
        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.iteminformation;
        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.iteminformation;
        if(s.getNodeType() == Node.TEXT_NODE)
        {
          return s.getNodeValue();
        }
      }
      return text;
    }
  }

Category:WebObjects