The SOAP With Attachment Example

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 are 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 which 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.

1 WSDL for SWA

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>

2 The Client

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());
    |   }
    }
}

3 The Server implementation

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; }
}

4 The Call Client

The Call Client demonstrates, how to send and receive attachments using 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());
    |   }
    }
                                                                           
}
Copyright © 2000-2003, Novell, Inc. All rights reserved.