Monday, March 2, 2015

SOAP With Attachments Client

In the enterprise world developing simple SOAP based web services are not enough and they have to deal with binary data like Imgae, PDF, Word, Xls and other documents. We will see simple SOAP client for streaming binary data.


Base64 Problem
The most popular way of sending the binary attachments to SOAP service is to encode the content as Base64. This method may well work for smaller size of attachments as the Base64 encoding is memory intensive operation. The entire content needs to loaded into memory and encoded using Base64. The encoded data needs to embedded within the SOAP body XML.

Also the encoded data size is roughly 37% more than the raw binary data. To make it work for large files you need to upgrade your JVM memory.

Streaming of Attachments (SOAP with attachments)
The memory intensive operation can be avoided using SOAP with attachments. The idea of SOAP with attachments is sames attaching the document to email. The SOAP Body contains only the reference to the binary file and binary file will be streamed outside of SOAP Envelope.

The following example shows the SOAP message and the attachments. This example is for Oracle UCM's CheckInUniversal operation. 

The SOAP message package is constructed using the Multipart/Related media type. The rules for the construction of SOAP message packages are as follows:
  1. The primary SOAP message must be carried in the root body part of the Multipart/Related structure. Consequently the type parameter of the Multipart/Related media header will always equal the Content-Type header for the primary SOAP 1.1 message, i.e., text/xml.
  2. Referenced MIME parts must contain either a Content-ID MIME header.
Content-Type: multipart/related; type="text/xml"; start="<test@example.com>"; boundary="----=_Part_12_21424854.1424891476173"
SOAPAction: "http://www.stellent.com/CheckIn/"
Content-Length: 1818


------=_Part_12_21424854.1424891476173
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <test@example.com>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:chec="http://www.stellent.com/CheckIn/">
   <soapenv:Header/>
   <soapenv:Body>
      <chec:CheckInUniversal>
         <chec:dDocName/>
         <chec:dDocTitle>TestStreaming-large</chec:dDocTitle>
         <chec:dDocType>Records</chec:dDocType>
         <chec:dDocAuthor>username</chec:dDocAuthor>
         <chec:dSecurityGroup>group</chec:dSecurityGroup>
         <chec:dDocAccount/>
         <chec:CustomDocMetaData>
            <chec:property>
               <chec:name>xLibrary</chec:name>
               <chec:value>library</chec:value>
            </chec:property>
            <chec:property>
               <chec:name>xesd_proj_name</chec:name>
               <chec:value>Test</chec:value>
            </chec:property>            
         </chec:CustomDocMetaData>
         <chec:primaryFile>
            <chec:fileName>TestUCM-large</chec:fileName>
         </chec:primaryFile>
      </chec:CheckInUniversal>
   </soapenv:Body>
</soapenv:Envelope>
------=_Part_12_21424854.1424891476173
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Content-ID: <primaryFile>

Hello
------=_Part_12_21424854.1424891476173--


The oracle UCM service expects the Content-ID of the attachment to be 'primaryFile' SOAP Part. The attachment file content is "Hello"

UploadStream Client

   1 
import java.io.File;
   2 
import java.io.IOException;
   3 
import java.util.Properties;
   4 
 
   5 
import javax.activation.DataHandler;
   6 
import javax.mail.Session;
   7 
import javax.mail.internet.MimeBodyPart;
   8 
import javax.mail.internet.MimeMessage;
   9 
import javax.mail.internet.MimeMultipart;
  10 
import javax.mail.internet.PreencodedMimeBodyPart;
  11 
 
  12 
import org.apache.commons.httpclient.Header;
  13 
import org.apache.commons.httpclient.HttpClient;
  14 
import org.apache.commons.httpclient.HttpException;
  15 
import org.apache.commons.httpclient.methods.PostMethod;
  16 
 
  17 
 
  18 
public class UploadStream {
  19 
        public static void main(String[] args) {
  20 
                String fileBaseName = "JDebug";
  21 
                String fileExtn = ".zip";
  22 
               
  23 
                for (int i=1; i<=1; i++) {
  24 
                        Upload uploadThread = new Upload("Thread-" + i, fileBaseName + i + fileExtn);
  25 
                        uploadThread.start();
  26 
                }
  27 
        }
  28 
       
  29 
        private static class Upload extends Thread {
  30 
                String name;
  31 
                String fileName;
  32 
                public Upload(String name, String fileName) {
  33 
                        super(name);
  34 
                        this.name = name;
  35 
                        this.fileName = fileName;
  36 
                }
  37 
               
  38 
                public void run() {
  39 
                        System.out.println("Thread["+ this.name +"] Started; Uploading " + "c:\\temp\\" + this.fileName);
  40 
                       
  41 
                        HttpClient client = new HttpClient();
  42 
                        PostMethod method = new PostMethod(
  43 
                                        "http://www.oracle.com:16200/_dav/cs/idcplg");
  44 
                        long start = System.currentTimeMillis();
  45 
                       
  46 
                        try {
  47 
                                                       
  48 
                                method.addRequestHeader("SOAPAction",
  49 
                                                "\"http://www.stellent.com/CheckIn/\"");
  50 
               
  51 
                                MimeMessage message = new MimeMessage(Session.getDefaultInstance( new Properties() ));
  52 
                                MimeMultipart mp = new MimeMultipart();
  53 
                               
  54 
                                // Create the first body part
  55 
                                StringBuffer requestXML = constructRequest(this.fileName);
  56 
                                long requestSize = requestXML.length();
  57 
                                MimeBodyPart rootPart = new PreencodedMimeBodyPart("8bit");
  58 
                                rootPart.setContentID("<test@example.com>");                       
  59 
                                rootPart.setDataHandler(new DataHandler(new RequestXmlDataSource(requestXML.toString())));
  60 
                               
  61 
                                mp.addBodyPart(rootPart, 0);
  62 
                               
  63 
                                File f = new File("c:\\temp\\" + this.fileName);
  64 
                                long attachmentSize = f.length();
  65 
                               
  66 
                                MimeBodyPart attachmentPart = new PreencodedMimeBodyPart("binary");
  67 
                                attachmentPart.setContentID("<primaryFile>");
  68 
                                attachmentPart.setDataHandler(new DataHandler( new AttachmentDataSource("c:\\temp\\" + this.fileName)));
  69 
                                mp.addBodyPart(attachmentPart);
  70 
                               
  71 
                                message.setContent(mp);
  72 
                                message.saveChanges();
  73 
                                                       
  74 
                               
  75 
                                String cType = message.getHeader("Content-Type")[0];
  76 
                                int idx = cType.indexOf("boundary");
  77 
                                int boundryLength = 0;
  78 
                                if (idx != -1) {
  79 
                                        boundryLength = cType.substring(idx+9).length();
  80 
                                }
  81 
                                                       
  82 
                                long contentLength = (boundryLength*3) +2 + requestSize + attachmentSize + 94 + 103 + 28;
  83 
                               
  84 
                                MimeMessageRequestEntity mimeMessageRequestEntity = new MimeMessageRequestEntity(
  85 
                                                message, contentLength);
  86 
                               
  87 
                                method.setDoAuthentication(true);
  88 
                                method.setRequestEntity(mimeMessageRequestEntity);
  89 
                               
  90 
 
  91 
                                method.addRequestHeader("Content-Length", String.valueOf(contentLength));
  92 
                                method.addRequestHeader("Content-Type", mimeMessageRequestEntity.getContentType());
  93 
                                method.getParams().setParameter("http.socket.timeout", new Integer(0));
  94 
                               
  95 
                                // execute the GET
  96 
                                int status = client.executeMethod(method);
  97 
                               
  98 
                                for(Header header : method.getRequestHeaders()) {
  99 
                                        System.out.println(header.getName() +": " + header.getValue());
 100 
                                }
 101 
                               
 102 
                                System.out
 103 
                                                .println(status + "\n" + method.getResponseBodyAsString());
 104 
 
 105 
                        } catch (HttpException e) {
 106 
                                System.out.println("Exception in Thread["+ this.name +"]");
 107 
                                e.printStackTrace();
 108 
                        } catch (IOException e) {
 109 
                                System.out.println("Exception in Thread["+ this.name +"]");
 110 
                                e.printStackTrace();
 111 
                        } catch (Exception e) {
 112 
                                System.out.println("Exception in Thread["+ this.name +"]");
 113 
                                e.printStackTrace();
 114 
                        } finally {
 115 
                                long end = System.currentTimeMillis();
 116 
                                System.out.println("Time taken by thread["+ this.name +"]: "+ (end-start));
 117 
                                // release any connection resources used by the method
 118 
                                method.releaseConnection();
 119 
                        }
 120 
                }
 121 
               
 122 
                public StringBuffer constructRequest(String fileName) {
 123 
                        StringBuffer request = new StringBuffer();
 124 
                        request.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:chec=\"http://www.stellent.com/CheckIn/\">\r\n" +
 125 
                                        "   <soapenv:Header/>" +
 126 
                                        "   <soapenv:Body>\r\n" +
 127 
                                        "      <chec:CheckInUniversal>\r\n" +
 128 
                                        "         <chec:dDocName/>\r\n" +
 129 
                                        "         <chec:dDocTitle>" + fileName +"</chec:dDocTitle>\r\n" +
 130 
                                        "         <chec:dDocType>Records</chec:dDocType>\r\n" +
 131 
                                        "         <chec:dDocAuthor>username</chec:dDocAuthor>\r\n" +
 132 
                                        "         <chec:dSecurityGroup>group</chec:dSecurityGroup>\r\n" +
 133 
                                        "         <chec:dDocAccount/>\r\n" +
 134 
                                        "         <chec:CustomDocMetaData>\r\n" +
 135 
                                        "            <chec:property>\r\n" +
 136 
                                        "               <chec:name>xLibrary</chec:name>\r\n" +
 137 
                                        "               <chec:value>Library</chec:value>\r\n" +
 138 
                                        "            </chec:property>\r\n" +
 139 
                                        "             <chec:property>\r\n" +
 140 
                                        "               <chec:name>xesd_proj_name</chec:name>\r\n" +
 141 
                                        "               <chec:value>Test</chec:value>\r\n" +
 142 
                                        "            </chec:property>            \r\n" +
 143 
                                        "         </chec:CustomDocMetaData>\r\n" +
 144 
                                        "         <chec:primaryFile>\r\n" +
 145 
                                        "            <chec:fileName>" + fileName +"</chec:fileName>\r\n" +
 146 
                                        "         </chec:primaryFile>\r\n" +
 147 
                                        "      </chec:CheckInUniversal>\r\n" +
 148 
                                        "   </soapenv:Body>\r\n" +
 149 
                                        "</soapenv:Envelope>");
 150 
                       
 151 
                        return request;
 152 
                }
 153 
        }
 154 
}

MimeMessageRequestEntity.java

  1 
import java.io.ByteArrayOutputStream;
  2 
import java.io.IOException;
  3 
import java.io.OutputStream;
  4 
 
  5 
import javax.mail.MessagingException;
  6 
import javax.mail.internet.MimeMessage;
  7 
import javax.mail.internet.MimeMultipart;
  8 
 
  9 
import org.apache.commons.httpclient.methods.RequestEntity;
 10 
 
 11 
public class MimeMessageRequestEntity implements RequestEntity {
 12 
        private final MimeMessage message;
 13 
        private byte[] buffer;
 14 
        private long contentLength = 0;
 15 
 
 16 
        public MimeMessageRequestEntity(MimeMessage message, long contentLength) {
 17 
                this.message = message;
 18 
                this.contentLength = contentLength;
 19 
        }
 20 
 
 21 
        public long getContentLength() {
 22 
               
 23 
                return contentLength;
 24 
        }
 25 
 
 26 
        public String getContentType() {
 27 
                try {
 28 
                        String header = message.getHeader("Content-Type")[0];
 29 
                        int ix = header.indexOf("boundary");
 30 
 
 31 
                        return "multipart/related;type=\"text/xml\"; "
 32 
                                        + "start=\"<test@example.com>\"; "
 33 
                                        + header.substring(ix);
 34 
                } catch (MessagingException e) {
 35 
                        e.printStackTrace();
 36 
                }
 37 
 
 38 
                return null;
 39 
        }
 40 
 
 41 
        public boolean isRepeatable() {
 42 
                return true;
 43 
        }
 44 
 
 45 
        public void writeRequest(OutputStream arg0) throws IOException {
 46 
                try {
 47 
                        if (buffer == null) {
 48 
                                arg0.write("\r\n".getBytes());
 49 
                                ((MimeMultipart) message.getContent()).writeTo(arg0);
 50 
                        } else
 51 
                                arg0.write(buffer);
 52 
                } catch (Exception e) {
 53 
                        e.printStackTrace();
 54 
                }
 55 
        }
 56 
 
 57 
        public MimeMultipart getMultiPartRequest() {
 58 
 
 59 
                try {
 60 
                        return ((MimeMultipart) message.getContent());
 61 
                } catch (IOException e) {
 62 
                        e.printStackTrace();
 63 
                } catch (MessagingException e) {
 64 
                        e.printStackTrace();
 65 
                }
 66 
 
 67 
                return null;
 68 
        }
 69 
}


RequestXmlDataSource.java

  1 
import java.io.ByteArrayInputStream;
  2 
import java.io.IOException;
  3 
import java.io.InputStream;
  4 
import java.io.OutputStream;
  5 
 
  6 
import javax.activation.DataSource;
  7 
 
  8 
public class RequestXmlDataSource implements DataSource {
  9 
        private String requestContent;
 10 
 
 11 
        public RequestXmlDataSource(String requestContent) {
 12 
                this.requestContent = requestContent;
 13 
        }
 14 
 
 15 
        public String getContentType() {
 16 
                return "text/xml; charset=UTF-8";
 17 
        }
 18 
 
 19 
        public InputStream getInputStream() throws IOException {
 20 
                byte[] bytes = requestContent.getBytes("UTF-8");
 21 
                return new ByteArrayInputStream(bytes);
 22 
        }
 23 
 
 24 
        public String getName() {
 25 
                return "";
 26 
        }
 27 
 
 28 
        public OutputStream getOutputStream() throws IOException {
 29 
                return null;
 30 
        }
 31 
}

AttachmentDataSource.java

  1 
import java.io.FileInputStream;
  2 
import java.io.IOException;
  3 
import java.io.InputStream;
  4 
import java.io.OutputStream;
  5 
 
  6 
import javax.activation.DataSource;
  7 
 
  8 
 
  9 
public class AttachmentDataSource implements DataSource
 10 
{
 11 
        private final String attachment;
 12 
 
 13 
        public AttachmentDataSource(String attachment)
 14 
        {
 15 
                this.attachment = attachment;
 16 
        }
 17 
 
 18 
        public String getContentType()
 19 
        {
 20 
                return "application/octet-stream";
 21 
        }
 22 
 
 23 
        public InputStream getInputStream() throws IOException
 24 
        {
 25 
                try
 26 
                {
 27 
                        return new FileInputStream(attachment);
 28 
                }
 29 
                catch( Exception e )
 30 
                {
 31 
                        throw new IOException( e.toString() );
 32 
                }
 33 
        }
 34 
 
 35 
        public String getName()
 36 
        {
 37 
                return attachment.substring(attachment.lastIndexOf("/")+1);
 38 
        }
 39 
 
 40 
        public OutputStream getOutputStream() throws IOException
 41 
        {
 42 
                return null;
 43 
        }
 44 
}




17 comments:

  1. Replies
    1. IEEE Final Year projects Project Center in Chennai are consistently sought after. Final Year Students Projects take a shot at them to improve their aptitudes, while specialists like the enjoyment in interfering with innovation. For experts, it's an alternate ball game through and through. Smaller than expected IEEE Final Year project centers ground for all fragments of CSE & IT engineers hoping to assemble. Final Year Project Domains for IT It gives you tips and rules that is progressively critical to consider while choosing any final year project point.

      JavaScript Training in Chennai

      JavaScript Training in Chennai

      The Angular Training covers a wide range of topics including Components, project projects for cseAngular Directives, Angular Services, Pipes, security fundamentals, Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training

      Delete
  2. Thank you a lot for providing individuals with a very spectacular possibility to read critical reviews from this site.

    Android Training in Bangalore

    ReplyDelete
  3. I found a lot of interesting information here. A really good post man, very thankful and hopeful that you will write many more posts like this one.
    kajal agarwal hot

    ReplyDelete
  4. TreasureBox is operated by a group of young, passionate, and ambitious people that are working diligently towards the same goal - make your every dollar count, as we believe you deserve something better.
    Check out the best
    Mattress
    entertainment unit

    ReplyDelete
  5. Established in 2016 SSDWebHosting.net is providing top quality domain and hosting services worldwide to
    our valued customers and trying to play a little role in their success.We offer about 500 distinctive gTlds and ccTlds
    to look over which includes old master class gTlds like .com, .net and .org, in addition this we also offer newly launched Tlds
    like .xyz, .online, .master, .office, .on, .top and .club. We can assist you with choosing the best fitting name. Let's bring your
    thought or business on the web. visit this site https://SSDWebHosting.net/ to know more.


    Do you wanna buy SSD Web Hosting visit here.
    Find best Cheap Web Hosting here.

    ReplyDelete

  6. نجار ابواب بالرياض نجار ابواب بالرياض
    تركيب ستائر بالرياض افضل شركة تركيب ستائر بالرياض
    تنظيف مكيفات بالرياض شركة غسيل مكيفات بالرياض
    شركة تنظيف افران الغاز بالرياض تنظيف افران بالرياض

    ReplyDelete
  7. The ability it provides for businesses and its users to create their own customized Salesforce tools in the cloud with its PaaS solution has strengthened the position of Salesforce in the CRM market. Salesforce also offers more flexibility for the users as they can construct modules as well as modify Salesforce to perform accurately for a specific industry or according to the company's specific requirements. Salesforce training in Hyderabad

    ReplyDelete
  8. You've decided to take your pet along on vacation. It will be more fun, and you won't have to worry about leaving a member of your family behind in an unfamiliar kennel.

    EntertainmentBee
    TheMoviesBio
    PetRefine
    ThePetsAbout

    ReplyDelete
  9. With special privileges and services, UEFA BET offers opportunities for small capitalists. Together ufa with the best websites that collect the most games With a minimum deposit starting from just 100 baht, you are ready to enjoy the fun with a complete range of betting that is available within the website

    ufabet , our one another option We are a direct website, not through an agent, where customers can have great confidence without deception The best of online betting sites is that our Ufa will give you the best price

    ReplyDelete
  10. อีกทั้งเรายังให้บริการ เกมสล็อต ยิงปลา แทงบอลออนไลน์ รองรับทุกการใช้งานในอุปกรณ์ต่าง ๆ HTML5 คอมพิวเตอร์ แท็บเล็ต สมาทโฟน คาสิโนออนไลน์ และมือถือทุกรุ่น เล่นได้ตลอด 24ชม. ไม่ต้อง Downloads เกมส์ให้ยุ่งยาก ด้วยระบบที่เสถียรที่สุดในประเทศไทย

    ReplyDelete
  11. หาคุณกำลังหาเกมส์ออนไลน์ที่สามารถสร้างรายได้ให้กับคุณ เรามีเกมส์แนะนำ เกมยิงปลา รูปแบบใหม่เล่นง่ายบนมือถือ คาสิโนออนไลน์ บนคอม เล่นได้ทุกอุปกรณ์รองรับทุกเครื่องมือ มีให้เลือกเล่นหลายเกมส์ เล่นได้ทั่วโลกเพราะนี้คือเกมส์ออนไลน์แบบใหม่ เกมยิงปลา

    ReplyDelete
  12. พร้อมทั้งยังมีคาสิโนที่ถ่ายทอดสดตลอด 24 ชั่วโมง ยูฟ่าเบท เว็บพนันออนไลน์ มีให้เล่นครบ ทั้งคาสิโน บาคาร่า สล็อต รูเล็ต ไฮโล และเกมส์ไพ่อื่นๆอีกมากมาย เรารวบรวมมาไว้ให้แล้วที่นี่ พร้อมโปรโมชั่นมากมาย สมัครยูฟ่าเบท เลยตอนนี้ เรามีความยินดีให้บริการทุกท่าน กับทีมงานมืออาชีพพร้อมแก้ไขปัญหา และรับใช้ทุกท่าน มีทีมงานคอยสนับสนุนบริการ และตอบคำถามคุณตลอด 24 ชม. ufa

    ReplyDelete
  13. Baccarat is money making and it's outstanding accessibility. The best In your case it's found that you'll find rather fascinating choices. And that is considered to be a thing that's rather different And it's very something that's rather happy to strike with The most wonderful, as well, is a very good alternative. Furthermore, it's a truly fascinating alternative. It's the simplest way which could generate profits. Superbly prepar The variety of best earning baccarat is the accessibility of generting by far the most cash. Almost as possible is so suitable for you A substitute which can be assured. To a wide variety of efficiency and availability And find out excellent benefits as well.บาคาร่า
    ufa
    ufabet
    แทงบอล
    แทงบอล
    แทงบอล

    ReplyDelete
  14. pgslot ซึ่งเกมคาสิโนออนไลน์เกมนี้เป็นเกมที่เรียกว่าเกม สล็อตเอ็กซ์โอ คุณรู้จักเกมส์เอ็กซ์โอหรือไม่ 90% ต้องรู้จักเกมส์เอ็กซ์โออย่างแน่นอนเพราะในตอนนี้เด็กนั้นเราทุกคนมักที่จะเอาก็ได้ขึ้นมา สล็อต เล่นเกมส์เอ็กซ์โอกับเพื่อนเพื่อนแล้วคุณรู้หรือไม่ว่าในปัจจุบันนี้เกมส์เอ็กซ์โอนั้นกลายมาเป็นเกมซะลอสออนไลน์ที่ให้บริการด้วยเว็บคาสิโนออนไลน์คุณสามารถเดิมพันเกมส์เอ็กซ์โอกับเว็บคาสิโนออนไลน์ได้โดยที่จะทำให้คุณนั้นสามารถสร้างกำไรจากการเล่นเกมส์เดิมพันออนไลน์ได้เราแนะนำเกมส์ชนิดนี้ให้คุณได้รู้จักก็เพราะว่าเชื่อว่าทุก

    ReplyDelete