Programming__WebObjects-Web Services-Sending Large Data
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.item;
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;
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;
if(s.getNodeType() == Node.TEXT_NODE)
{
return s.getNodeValue();
}
}
return text;
}
}
Category:WebObjects