In this blog, I would like to generate an HTML Form based request from SAP PI HTTP adapters. In the new java based HTTP adapter, SAP has made it easier to create form based request using extra features in the communication channel. For example in HTTP_AAE adapter, you can now specify that the HTTP request is a multi-part form request and you can also send attachments for a file upload.

HTTP_AAE.png

However in this blog, I will be solving this problem by manually creating Multipart request in JAVA Mapping. This way you can even use plain HTTP adapter if you are using lower versions of PI.

First thing we need to understand is how a multipart request actually looks like. You should visit this URL http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for official specification on multipart upload. In the section 13.4.2 you will find the specification for multipart request.

specification.JPG

I will explain how the PI HTTP request should look like. Basically If your HTML request(for web page testing) is like this:

html request.JPG

Then multipart request(body) which you should generate from PI should be like this:(This should also be the output of java mapping)

multipart request.JPG

Here boundary is very important. I have used a constant boundary value. This boundary value is specified in java mapping while generating such request and also the same boundary is specified in HTTP Receiver communication channel in the content type field.

CC.JPG

Now let’s look at the java mapping code which is used to generate such a request. The code, I have used is pretty simple.

package com.test.sap.pi.file;

import java.io.*;

@SuppressWarnings(“deprecation”)

public class CreateForm implements StreamTransformation {

     private String boundary;

     private static final String LINE_FEED = “\r\n”;

     private HttpURLConnection httpConn;

     private String charset;

     private String body;

     private OutputStream outputStream;

     private PrintWriter writer;

     public void execute(InputStream arg0, OutputStream arg1)

  throws StreamTransformationException {

  // TODO Auto-generated method stub

         // creates a unique boundary based on time stamp

        // boundary = “===” + System.currentTimeMillis() + “===”;

         boundary = “–ejjeeffe1”;

         body = “Content-Type: multipart/form-data; boundary=”;

         body = body + boundary + LINE_FEED + LINE_FEED;

//        body.concat(boundary);

         addFormField(“event”,”Import File” );

         addFormField(“Filename”,”TestFile.zip” );

  

         body = body + boundary;

  

         body = body + LINE_FEED + “Content-Disposition: form-data; name=\”” + “content” +

         “\”” + “;” + “filename=\”” + “TestFile.zip” + “\”” +

          LINE_FEED + “Content-Type: application/zip” + LINE_FEED +

          “Content-Transfer-Encoding: binary” + LINE_FEED + LINE_FEED;

 

         byte[] buffer = new byte[4096];

         byte[] message = body.getBytes();

     //    int bytesRead = -1;

         ByteArrayOutputStream outbody = new ByteArrayOutputStream();

   

         try {

  arg1.write(message);

  int len = -1;

  while ((len = arg0.read(buffer)) != -1) {

  arg1.write(buffer, 0, len);

  }

  } catch (IOException e) {

  e.printStackTrace();

  }

  

        String endchar = LINE_FEED + boundary;

  try {

  arg1.write(endchar.getBytes());

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  public void setParameter(Map arg0) {

  // TODO Auto-generated method stub

  }

    /**

     * Addsa form field to the request

     * @param name field name

     * @param value field value

     */

    public void addFormField(String name, String value) {

    body = body + boundary + LINE_FEED + “Content-Disposition: form-data; name=\”” + name + “\””

    + LINE_FEED + “Content-Type: text/plain” + LINE_FEED + LINE_FEED

    + value + LINE_FEED;

    }

}

The contents of the file in this case are directly supplied in the input message. In my test case, sender is an FTP which picks up ‘zip’ file from FTP. However we can also use support scenarios where file is supplied as an attachment (for example if the sender is SOAP etc.). In that case java mapping code will be slightly changed to read file binary data from attachment.

Hopefully this gives you an idea of how to create multipart form request. I would still recommend to use standard feature in HTTP_AAE adapter to create form upload where ever possible. This way, system will generate request for you. Use this method of java mapping only when standard feature is not possible.

This blog tries to explain in simple way, how a multipart HTML request looks like, how it can be easily generated from XI and provides java code to achieve a simple scenario.

Reference:  http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

                    http://scn.sap.com/community/pi-and-soa-middleware/blog/2012/08/12/http-test-tool-for-sap-pi-73

To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

Leave a Reply