The Novell exteNd WSSDK supports SOAP With Attachment(SWA). A SOAP message may need to be transmitted together with attachments of various sorts, ranging from fascimile images of legal documents to engineering drawings. Such data is often combined in binary format.
This example illustrates sending and receiving the contents of a text file
and a jpeg image as attachments. There are WSDL constructs that indicate whether
the SOAP message is with attachments. The WSDL defines two operations,
echoMIMEString
that has a string part as input and output, and
echoMimeImage
that has
an java.awt.Image
as an input and output.
The mime:multipartRelated
element indicates that the input or
output message is a multipart message. The mime:part
elements indicate
how many parts are there and names of those parts. The mime:content
element indicates which parts of the message are secondary MIME parts and what
are their content types.
Below is the WSDL for the service.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="AttachmentAppService" targetNamespace="urn:MIMEService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="urn:MIMEService" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <message name="echoMIMEString"> <part name="str_in" type="xsd:string"/> </message> <message name="echoMIMEStringResponse"> <part name="str_out" type="xsd:string"/> </message> <message name="echoMIMEImage"> <part name="img_in" type="xsd:base64Binary"/> </message> <message name="echoMIMEImageResponse"> <part name="img_out" type="xsd:base64Binary"/> </message> <portType name="MIMEPortType"> <operation name="echoMIMEString"> <input message="tns:echoMIMEString" name="echoMIMEString"/> <output message="tns:echoMIMEStringResponse" name="echoMIMEStringResponse"/> </operation> <operation name="echoMIMEImage"> <input message="tns:echoMIMEImage" name="echoMIMEImage"/> <output message="tns:echoMIMEImageResponse" name="echoMIMEImageResponse"/> </operation> </portType> <binding name="MIMEPortBinding" type="tns:MIMEPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="echoMIMEString"> <soap:operation soapAction="urn:MIMEService/echoMIMEString" style="rpc"/> <input name="echoMIMEString"> <mime:multipartRelated> <mime:part name="part1"> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:MIMEService" use="encoded"/> </mime:part> <mime:part name="part2"> <mime:content part="str_in" type="text/plain"/> </mime:part> </mime:multipartRelated> </input> <output name="echoMIMEStringResponse"> <mime:multipartRelated> <mime:part name="part1"> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:AttachmentService" use="encoded"/> </mime:part> <mime:part name="part2"> <mime:content part="str_out" type="text/plain"/> </mime:part> </mime:multipartRelated> </output> </operation> <operation name="echoMIMEImage"> <soap:operation soapAction="urn:MIMEService/echoMIMEImage" style="rpc"/> <input name="echoMIMEImage"> <mime:multipartRelated> <mime:part name="part1"> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:MIMEService" use="encoded"/> </mime:part> <mime:part name="part2"> <mime:content part="img_in" type="image/jpeg"/> </mime:part> </mime:multipartRelated> </input> <output name="echoMIMEImageResponse"> <mime:multipartRelated> <mime:part name="part1"> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:AttachmentService" use="encoded"/> </mime:part> <mime:part name="part2"> <mime:content part="img_out" type="image/jpeg"/> </mime:part> </mime:multipartRelated> </output> </operation> </binding> <service name="MIMEService"> <port binding="tns:MIMEPortBinding" name="MIMEPort"> <soap:address location="http://localhost:9090/mime"/> </port> </service> </definitions>
The client simply passes the content of the file to the remote method and then the stub serializes the content as a mime part in the SOAP message.
package mime; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.StringWriter; import java.io.IOException; import javax.xml.rpc.Stub; import javax.naming.InitialContext; import java.awt.image.BufferedImage; import java.awt.Component; import java.awt.Frame; import java.awt.Graphics2D; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Toolkit; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.ImageFormatException; public class Client { private static final float JPEG_IMAGE_QUALITY = 1.0F; public static void main(String[] args) throws Exception { | // get the initial context | InitialContext ctx = new InitialContext(); | | // lookup the service for Types | MIMEService svc = (MIMEService) | ctx.lookup("xmlrpc:soap:mime.MIMEService"); | | // get the Types stub | MIMEPortType mimeport = (MIMEPortType) svc.getMIMEPort(); | | // set the end point address | if (args.length > 0) | ((Stub)mimeport)._setProperty( | "javax.xml.rpc.service.endpoint.address", args[0]); | | echoMimeString(mimeport); | echoMimeImage(mimeport); | System.exit(0); } public static void echoMimeString(MIMEPortType stub) throws Exception { | System.out.println("\n\n********** EchoMimeString **********"); | | // Open and read the file LICENSE.html | FileInputStream fis = new FileInputStream("LICENSE.html"); | StringWriter sw = new StringWriter(); | int c; | while((c = fis.read()) != -1) sw.write(c); | | // | String content = sw.toString(); | System.out.println("sending content********************"); | System.out.println(content); | System.out.println("********************"); | System.out.println("\n\n"); | | // | String result = stub.echoMIMEString(content); | System.out.println("recieved content********************"); | System.out.println(result); | System.out.println("********************"); } public static void echoMimeImage(MIMEPortType stub) throws Exception { | System.out.println("\n\n********** EchoMimeImage **********"); | // read in the image file extend.jpg | Toolkit tk = Toolkit.getDefaultToolkit(); | Image image = tk.getImage("eXtend.jpg"); | | // send and receive the image | System.out.println("sending image********************"); | Image result = stub.echoMIMEImage(image); | System.out.println("received image********************"); | | // write the contents of image to file | FileOutputStream os = new FileOutputStream("echo.jpg"); | BufferedImage bImage = null; | MediaTracker tracker = new MediaTracker(new Frame()); | try { | | tracker.addImage(result, 0); | | tracker.waitForID(0); | | bImage = new BufferedImage(result.getWidth(null), | | result.getHeight(null), BufferedImage.TYPE_INT_RGB); | | Graphics2D g = bImage.createGraphics(); | | g.drawImage(result, 0, 0, null); | | | | JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); | | JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bImage); | | param.setQuality(JPEG_IMAGE_QUALITY, false); | | encoder.setJPEGEncodeParam(param); | | encoder.encode(bImage); | | os.flush(); | | os.close(); | | System.out.println("Wrote image to echo.jpg"); | } catch (InterruptedException ie) { | | ie.printStackTrace(); | | throw new IOException("Error: while getting image contents - " + | | ie.getMessage()); | } catch(IOException iex) { | | iex.printStackTrace(); | | throw new IOException("Error: while writing JPEG image - " + | | iex.getMessage()); | } catch(ImageFormatException fex) { | | fex.printStackTrace(); | | throw new IOException("Error: while encoding JPEG image - " + | | fex.getMessage()); | } } }
The server is a simple echo server. It just returns the object it receives.
package mime; import java.rmi.Remote; import java.rmi.RemoteException; public class Server extends MIMEPortType_ServiceSkeleton { public java.lang.String echoMIMEString(java.lang.String str) throws RemoteException { return str; } public java.awt.Image echoMIMEImage(java.awt.Image img) throws RemoteException { return img; } }
The call client demonstrates how to send and receive attachments using the
Call
API. You have to set the ATTACHMENTS
property on the
call object to specify which parameters are attachments. The property value should
be a string array of length equals to number of added parameters, plus 1 if there
is a return value expected. If the parameter is attachment, its corresponding element
in the array should be set to its MIME contentType.
package mime; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.StringWriter; import java.io.IOException; import java.awt.image.BufferedImage; import java.awt.Component; import java.awt.Frame; import java.awt.Graphics2D; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Toolkit; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.ImageFormatException; import javax.xml.namespace.QName; import javax.xml.rpc.Call; import javax.xml.rpc.Service; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceFactory; import com.sssw.jbroker.web.encoding.DefaultTypeMappingRegistry; public class CallClient { private static final float JPEG_IMAGE_QUALITY = 1.0F; private final static String URI = "urn:MIMEService"; public static void main(String[] args) throws Exception { | System.setProperty(ServiceFactory.SERVICEFACTORY_PROPERTY, | "com.sssw.jbroker.web.xml.rpc.ServiceFactoryDelegate"); | | // create a Novell exteNd WSSDK service factory | ServiceFactory factory = ServiceFactory.newInstance(); | | //create the dynamic service | QName qname = new QName(URI, "MIMEService"); | Service svc = (Service) factory.createService(qname); | | //create the dynamic call | QName portType = new QName(URI, "MIMEPort"); | Call call = svc.createCall(portType); | | QName input = new QName(URI, "echoMIMEImage"); | QName output = new QName(URI, "echoMIMEResponse"); | | //add input parameter | call.addParameter("img_in", input, java.awt.Image.class, ParameterMode.IN); | | //set return type | javax.xml.namespace.QName r = new javax.xml.namespace.QName("", "img_out"); | call.setReturnType(r, java.awt.Image.class); | | //set call properties | call.setTargetEndpointAddress(args.length > 0 ? args[0] : | "http://localhost:9090/mime"); | | call.setProperty(Call.SOAPACTION_URI_PROPERTY, | "urn:MIMEService/echoMIMEImage"); | | call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc"); | call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY, | "http://schemas.xmlsoap.org/soap/encoding/"); | | call.setPortTypeName(portType); | call.setOperationName(input); | | //set attachments array property | call.setProperty(com.sssw.jbroker.web.portable.Stub.ATTACHMENTS, | new String[] {"image/jpeg", "image/jpeg"}); | | //create input parameters for attachment | Toolkit tk = Toolkit.getDefaultToolkit(); | Image image = tk.getImage("eXtend.jpg"); | | Object[] params = { image }; | | | //invoke the operation | Image result = (Image) call.invoke(params); | | System.out.println("writing echoed image to file echo.jpg"); | writeImageToFile(result); | System.exit(0); | } public static void writeImageToFile(Image result) throws Exception { | // write the contents of image to file | FileOutputStream os = new FileOutputStream("echo.jpg"); | BufferedImage bImage = null; | MediaTracker tracker = new MediaTracker(new Frame()); | try { | | tracker.addImage(result, 0); | | tracker.waitForID(0); | | bImage = new BufferedImage(result.getWidth(null), | | result.getHeight(null), BufferedImage.TYPE_INT_RGB); | | Graphics2D g = bImage.createGraphics(); | | g.drawImage(result, 0, 0, null); | | | | JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); | | JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bImage); | | param.setQuality(JPEG_IMAGE_QUALITY, false); | | encoder.setJPEGEncodeParam(param); | | encoder.encode(bImage); | | os.flush(); | | os.close(); | | System.out.println("Wrote image to echo.jpg"); | } catch (InterruptedException ie) { | | ie.printStackTrace(); | | throw new IOException("Error: while getting image contents - " + | | ie.getMessage()); | } catch(IOException iex) { | | iex.printStackTrace(); | | throw new IOException("Error: while writing JPEG image - " + | | iex.getMessage()); | } catch(ImageFormatException fex) { | | fex.printStackTrace(); | | throw new IOException("Error: while encoding JPEG image - " + | | fex.getMessage()); | } } }
Please refer to the README for detailed instructions on compiling, deploying and running the example.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.