Version 3.1 by Pascal Robert on 2007/09/03 19:36

Show last authors
1 === Kristoff Cossement ===
2
3 Soap with mime attachments was indeed the way to go.
4
5 Remark: this only works with java 1.4.2//09 (I did not get it working with java 1.5.x)//
6
7 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.
8 You also need the java mail and java activation framework from sun.
9
10 ==== Client.java ====
11
12 {{code}}
13
14 import javax.xml.soap.SOAPConnectionFactory;
15 import javax.xml.soap.*;
16 import javax.xml.transform.stream.*;
17 import javax.xml.transform.*;
18 import java.io.*;
19 import org.apache.axis.attachments.AttachmentPart;
20 import org.apache.axis.message.*;
21 import javax.activation.DataHandler;
22 import javax.activation.FileDataSource;
23 import javax.xml.soap.SOAPElement;
24 import java.util.*;
25 import javax.mail.*;
26
27 public class Client {
28
29 public static File resize(String sPath)
30 {
31 File file = new File(sPath);
32
33
34 String endPoint = "http://localhost:55555/cgi-bin/WebObjects/project.woa/ws/FileUpload";
35 try{
36 SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
37 SOAPMessage message = (javax.xml.soap.SOAPMessage)MessageFactory.newInstance().createMessage();
38 SOAPPart part = message.getSOAPPart();
39 SOAPEnvelope envelope = (org.apache.axis.message.SOAPEnvelope)part.getEnvelope();
40 SOAPBody body = (org.apache.axis.message.SOAPBody)envelope.getBody();
41 SOAPBodyElement operation = (org.apache.axis.message.SOAPBodyElement)body.addBodyElement(
42 envelope.createName("upload",
43 "ns",
44 "http://localhost:55555/cgi-bin/WebObjects/project.woa/ws/FileUpload"));
45 operation.setEncodingStyle("http://schemas.xmlsoaporg/soap/encoding/");
46
47 DataHandler dh = new DataHandler(new FileDataSource(file));
48 AttachmentPart attachment = (org.apache.axis.attachments.AttachmentPart)message.createAttachmentPart(dh);
49 SOAPElement filename = operation.addChildElement("filename","");
50 SOAPElement source = operation.addChildElement("source","");
51 message.addAttachmentPart(attachment);
52 filename.addTextNode(file.getName());
53 source.addTextNode(attachment.getContentId());
54
55 SOAPMessage result = connection.call(message,endPoint);
56 System.out.println(result);
57 part = result.getSOAPPart();
58 envelope = (org.apache.axis.message.SOAPEnvelope)part.getEnvelope();
59 body = (org.apache.axis.message.SOAPBody)envelope.getBody();
60
61 if(!body.hasFault())
62 {
63 System.out.println("answer : "+body);
64
65 }
66 }
67 catch(Exception e)
68 {
69 e.printStackTrace();
70 }
71 return null;
72 }
73
74 public static void main(String[] args) {
75
76 try {
77
78 resize(args[0]);
79
80 }
81 catch (Exception e) {
82 System.out.println(e.getMessage());
83 }
84 }
85 }
86
87 {{/code}}
88
89 ==== ====
90
91 ===== Webobjects Application .java =====
92
93 override dispatchRequest
94
95 {{code}}
96
97   public WOResponse dispatchRequest(WORequest request)
98 {
99 WOResponse result = null;
100 String sURI = request.uri();
101 NSLog.debug.appendln("Accessing " + sURI);
102
103 Pattern p = Pattern.compile("/ws/FileUpload");
104 Matcher m = p.matcher(sURI);
105 if(m.find())
106 {
107 String sContType = request.headerForKey("content-type");
108 p = Pattern.compile("multipart/related");
109 m = p.matcher(sContType);
110 if(m.find())
111 {
112 result = Dispatcher.handleFileUpload(request);
113 }
114 else
115 {
116 result = super.dispatchRequest(request);
117 }
118 }
119 else
120 {
121 result = super.dispatchRequest(request);
122 }
123
124 return result;
125
126 }
127
128 {{/code}}
129
130 ===== Dispatcher.java =====
131
132 {{code}}
133
134   //
135 // Dispatcher.java
136 // project
137 //
138 // Created by admin on 5/5/06.
139 // Copyright 2006 __MyCompanyName__. All rights reserved.
140 //
141 import com.webobjects.foundation.*;
142 import com.webobjects.appserver.*;
143 import com.webobjects.eocontrol.*;
144
145 import java.io.*;
146 import java.util.regex.*;
147 import org.w3c.dom.*;
148 import javax.xml.transform.*;
149 import javax.xml.transform.stream.*;
150 import javax.xml.transform.dom.*;
151 import javax.xml.parsers.*;
152 import org.apache.axis.attachments.*;
153
154
155 public class Dispatcher {
156
157 public static WOResponse handleFileUpload(WORequest request)
158 {
159 String sContType = request.headerForKey("content-type");
160 String sSoapXml = "";
161 InputStream requestStream = request.contentInputStream();
162
163 String sTempDir = System.getProperty("java.io.tmpdir");
164 String timestamp =(new Long(System.currentTimeMillis())).toString();
165 File fTempFile = new File(sTempDir+"/"+timestamp);
166 File fSavedFile = new File(sTempDir+"/"+timestamp+".out");
167
168 try
169 {
170 BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(fTempFile));
171 byte[] buffer = new byte[32 * 1024];
172 int bytesRead = 0;
173 while ((bytesRead = requestStream.read(buffer)) != -1)
174 {
175 fOut.write(buffer, 0, bytesRead);
176 }
177 fOut.close();
178 }
179 catch (Exception e)
180 {
181 NSLog.debug.appendln(e.getMessage());
182 }
183
184 try
185 {
186 InputStream iStream = new FileInputStream(fTempFile);
187
188 MultiPartRelatedInputStream mis = new MultiPartRelatedInputStream(sContType,iStream);
189 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
190 Document doc = factory.newDocumentBuilder().parse(mis);
191 sSoapXml = toString(doc);
192 NSLog.debug.appendln("SOAP Envelope: " + sSoapXml);
193 mis.close();
194 iStream.close();
195
196 Node nEnvelope = getNamedChildNode(doc,"Envelope");
197 if(null != nEnvelope)
198 {
199 Node nBody = getNamedChildNode(nEnvelope,"Body");
200 if(null != nBody)
201 {
202 NSArray nSubNodes = getElementChildNodes(nBody);
203 if((null != nSubNodes) && (nSubNodes.count() > 0))
204 {
205 Node nFileUpload = (Node)nSubNodes.get(0);
206 nSubNodes = getElementChildNodes(nFileUpload);
207 if((null != nSubNodes) && (nSubNodes.count() > 1))
208 {
209 Node nFileName = (Node)nSubNodes.get(0);
210 Node nData = (Node)nSubNodes.get(1);
211
212 String sFileName = getTextFromNode(nFileName);
213 String sFileMimeID = getTextFromNode(nData);
214
215 fSavedFile = new File(sTempDir+"/"+sFileName);
216
217 Pattern pattern = Pattern.compile("(boundary=\".+?\")");
218 Matcher match = pattern.matcher(sContType);
219 if(match.find())
220 {
221 String boundary= match.group(1);
222 String sSubContentType = "multipart/related; type=\"text/xml\"; start=\"<"+sFileMimeID+">\"; "+boundary;
223 iStream = new FileInputStream(fTempFile);
224 mis = new MultiPartRelatedInputStream(sSubContentType,iStream);
225 try
226 {
227 BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(fSavedFile));
228 byte[] buffer = new byte[32 * 1024];
229 int bytesRead = 0;
230 while ((bytesRead = mis.read(buffer)) != -1)
231 {
232 fOut.write(buffer, 0, bytesRead);
233 }
234 mis.close();
235 fOut.close();
236 }
237 catch (Exception e)
238 {
239 System.out.println(e.getMessage());
240 //throw new IOException(me + " failed, got: " + e.toString());
241 }
242 }
243 }
244 }
245 }
246 }
247 }
248 catch(Exception e)
249 {
250 e.printStackTrace();
251 }
252
253
254 WOResponse result = new WOResponse();
255 result.setContent( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
256 "<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"+
257 "<soapenv:Body>\n"+
258 "<ns:uploadResponse soapenv:encodingStyle=\"http://schemas.xmlsoaporg/soap/encoding/\" xmlns:ns=\"http://localhost:55555/cgi-bin/WebObjects/project.woa/ws/FileUpload\">\n"+
259 "<ns:uploadReturn xsi:type=\"xsd:boolean\">true</ns:uploadReturn>\n"+
260 "</ns:uploadResponse>\n"+
261 "</soapenv:Body>\n"+
262 "</soapenv:Envelope>");
263
264
265 result.setHeader("text/xml; charset=utf-8","content-type");
266
267
268 return result;
269
270 }
271
272
273 static public String toString(Document document) {
274 String result = null;
275
276 if (document != null) {
277 StringWriter strWtr = new StringWriter();
278 StreamResult strResult = new StreamResult(strWtr);
279 TransformerFactory tfac = TransformerFactory.newInstance();
280 try {
281 Transformer t = tfac.newTransformer();
282 t.setOutputProperty(OutputKeys.ENCODING, "utf-8");
283 t.setOutputProperty(OutputKeys.INDENT, "yes");
284 t.setOutputProperty(OutputKeys.METHOD, "xml"); //xml, html, text
285 t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
286 t.transform(new DOMSource(document.getDocumentElement()), strResult);
287 } catch (Exception e) {
288 System.err.println("XML.toString(Document): " + e);
289 }
290 result = strResult.getWriter().toString();
291 }
292
293 return result;
294 }
295
296 static public Node getNamedChildNode(Node n, String sChildNodeName)
297 {
298
299 NodeList nl = n.getChildNodes();
300
301 for(int i=0;i<nl.getLength();i++)
302 {
303 Node s = nl.item(i);
304 String sChild = s.getNodeName();
305 if(sChildNodeName.equalsIgnoreCase(sChild) || sChild.endsWith(":"+sChildNodeName))
306 {
307 NSLog.debug.appendln("childnode = " + s.getNodeName());
308 return s;
309 }
310 }
311
312 return null;
313
314 }
315 static public NSArray getElementChildNodes(Node n)
316 {
317 NSMutableArray elements = new NSMutableArray();
318 NodeList nl = n.getChildNodes();
319
320 for(int i=0;i<nl.getLength();i++)
321 {
322 Node s = nl.item(i);
323 if(s.getNodeType() == Node.ELEMENT_NODE)
324 {
325 NSLog.debug.appendln("childnode = " + s.getNodeName());
326 elements.addObject(s);
327 }
328 }
329
330 return elements;
331 }
332 static public String getTextFromNode(Node n)
333 {
334 String text = "";
335
336 NodeList nl = n.getChildNodes();
337
338 for(int i=0;i<nl.getLength();i++)
339 {
340 Node s = nl.item(i);
341 if(s.getNodeType() == Node.TEXT_NODE)
342 {
343 return s.getNodeValue();
344 }
345 }
346 return text;
347 }
348 }
349
350 {{/code}}