cancel
Showing results for 
Search instead for 
Did you mean: 

REST RECIVER - FORM DATA WITH ZIP ATTACHMENT

0 Kudos

Hi Experts,

I have the following scenario XI->PI->REST FormData, this is the service i need to send the data.

The error can be ignored, what is needed now is to be able to consume the service correctly.

The following configuration is used in the REST communication Channel.

This is the information that is sent using the next java mapping. The value of the .zip is being sent in base64 to be able to send it through the form data service.

package javaMapping;

import java.io.*;
import java.util.Map;
import com.sap.aii.mapping.api.*;
import org.apache.commons.*;
import org.apache.commons.net.util.Base64;

@SuppressWarnings("deprecation")

public class javaMappingFormDataFile 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;
	
	private String valHash;
	private String fileName;
	private String fileData;

	public void execute(InputStream arg0, OutputStream arg1) throws StreamTransformationException {
		
		valHash = "cb21904fcc528668a98a5002247908364570a2ce63bf9cf05c9e50291d213ba1";
		fileName = "20492836282-PND-20220217-1.zip";
		fileData = "UEsDBBQACAAIAPF+V1QAAAAAAAAAABcAAAAKACAAcHJ1ZWJhLnR4dFVUDQAHRp8WYkifFmJGnxZidXgLAAEE9QEAAAQUAAAACygqTU1K1ElJLU5J1SnI1EnUKS7NSywBAFBLBwjEckU4GQAAABcAAABQSwMEFAAIAAgA8X5XVAAAAAAAAAAAPgIAABUAIABfX01BQ09TWC8uX3BydWViYS50eHRVVA0AB0afFmJInxZiT58WYnV4CwABBPUBAAAEFAAAAGNgFWNnYGJg8E1MVvAPVohQgAKQGAMnEBsxMDDxAGkgn8mOgSjgGBISBGGBdDCGABmv0JSwQsX5GRjEk/Nz9RILCnJS9UJSK0pc85LzUzLz0sHKGJOBhAADgxRCTU5icUlpcWpKSmJJqnJAMMQ4xmIg4QE0DqEuNzE5ByK3G0hoMTCoIMmlliQC9SdaxWf7uniWpOaGFqcWhSSmF4PVPwUSkQwM5ljUA5X7JCal5sQnlqflpSUZ5ZSXllSUG2WUlJaXJWVWJpekFgI1l5ak6VpYGxqbGBmaW1qYuM0XSwK7pOQ+L4hiYSjaJZ76e4b/z43CbA+v3b84g7hgRQdJBTmZxSUGBgs4oIHACJVgRFPI+WmORXHowReOWbqc+yYek/14m/8E1+/cQ8kB/0SMDjj5/2iRfOXtdb7XtuZV46Gg+7xvnx3/IsjtPzPafWVHytTzJz69P3BbfMHzYnnx618Ewl5frth67rLkNn8360wAUEsHCKES2L9wAQAAPgIAAFBLAQIUAxQACAAIAPF+V1TEckU4GQAAABcAAAAKACAAAAAAAAAAAACkgQAAAABwcnVlYmEudHh0VVQNAAdGnxZiSJ8WYkafFmJ1eAsAAQT1AQAABBQAAABQSwECFAMUAAgACADxfldUoRLYv3ABAAA+AgAAFQAgAAAAAAAAAAAApIFxAAAAX19NQUNPU1gvLl9wcnVlYmEudHh0VVQNAAdGnxZiSJ8WYk+fFmJ1eAsAAQT1AQAABBQAAABQSwUGAAAAAAIAAgC7AAAARAIAAAAA";
		boundary = "-ejjeeffe1";

		byte[] fileDataByte = fileData.getBytes();

		body = boundary;
		body = body + LINE_FEED + "Content-Disposition: form-data; name=\"" + "valHash" + LINE_FEED + valHash + LINE_FEED + LINE_FEED;
		body = body + boundary;
		body = body + LINE_FEED + "Content-Disposition: form-data; name=\"" + "content" +

				"\"" + ";" + "filename=\"" + fileName + "\"" +

				LINE_FEED + "Content-Type: application/zip" + LINE_FEED +

				"Content-Transfer-Encoding: binary" + LINE_FEED + LINE_FEED;

		byte[] message = body.getBytes();
		
		byte[] buffer = new byte[4096];

		ByteArrayOutputStream outbody = new ByteArrayOutputStream();

		try {

			arg1.write(message);
			arg1.write(fileDataByte);

		} catch (IOException e) {

			e.printStackTrace();

		}

		String endchar = LINE_FEED + boundary;

		try {

			arg1.write(endchar.getBytes());

		} catch (Exception e) {

			e.printStackTrace();

		}

	}

	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;

	}

	@Override
	public void setParameter(Map arg0) {
		// TODO Auto-generated method stub
		
	}

}

But submitting i get the following response.

The SWC was removed from the ICO, based on the recommendation obtained from a blog, but the error still persists.

Any suggestions regarding this scenario ?

I'll be waiting for your comments,

Thanks.

References:

The Mystery of ‘Content is not allowed in prolog’ | SAP Blogs

CSV Multi-Part Form-Data Upload as Attachment using HTTP_AAE Adapter in SAP PI 7.5 | SAP Blogs

Accepted Solutions (1)

Accepted Solutions (1)

stefan_grube
Active Contributor

uncheck the parameters "set Multipart" and "keep attachments"
If you use those parameters, the HTTP adapter will create a multipart/related which you don't want.

As I have mentioned before, the transfer encoding should be base64:

"Content-Transfer-Encoding: base64" + LINE_FEED + LINE_FEED;

I think there is a second linefeed missing before the last boundary.

String endchar = LINE_FEED + LINE_FEED + boundary;
0 Kudos

Hi Stefan,

We made the indicated changes, and the service has already responded correctly.

Thanks,

Best Regards.

Answers (4)

Answers (4)

Muniyappan
Active Contributor

Could you please show the complete message processing logs? is it happening before calling endpoint?

Can you uncheck the support attachment and try? I have recently worked on posting csv attachment and I am able to do it using rest receiver channel.

Why is double quote missing in ValHash in closing?

Basically your request should look like the postman request. In your postman, can you go to code section and show us how does it looks like?

If you want to know what is happening, I would suggest use xpi inspector and analysis the call trace. This will help to find out the issue.

stefan_grube
Active Contributor

It should be Content-Transfer-Encoding: base64.

The boundary must start with two hyphens: --ejjeeffe1

The last boundary must also end with two hyphens: --ejjeeffe1--

Instead of the REST adapter, I recommend using the HTTP_AAE adapter.
You should add the content type as

multipart/form-data; boundary="ejjeeffe1"


Maybe you can also use the HTTP_AAE adapter on the sender side.

Although the REST adapter provides the option multipart/form-data, I did not find a way to configure and use it correctly.

0 Kudos

Hi stefan,

Thanks for your recommendation, we put it to the test and this is what we currently generate.

Content-Type: multipart/form-data; boundary=ejjeeffe1

--ejjeeffe1
Content-Disposition: form-data; name="valHash"
Content-Type:text/plain
cb21904fcc5286xxxxxxxxxxxxxxxxa2ce63bf9cf05c9e50291d213ba1

--ejjeeffe1
Content-Disposition: form-data; name="archivo";filename="20492836282-PND-20220217-1.zip"
Content-Type: application/zip
Content-Transfer-Encoding: binary

UEsDBBQACAAIAPF+V1QxxxxxxxxxxxxxxxxxxxxxxxxxAEE9QEAAAQUAAAACygqTU1K1ElJLU5J1SnI1EnUKS7NSywBAFBLBwjEckU4GQAAABcAAABQSwMEFAAIAAgA8X5XVAAAAAAAAAAAPgIAABUAIABfX01BQ09TWC8uX3BydWViYS50eHRVVA0AB0afFmJInxZiT58WYnV4CwABBPUBAAAEFAAAAGNgFWNnYGJg8E1MVvAPVohQgAKQGAMnEBsxMDDxAGkgn8mOgSjgGBISBGGBdDCGABmv0JSwQsX5GRjEk/Nz9RILCnJS9UJSK0pc85LzUzLz0sHKGJOBhAADgxRCTU5icUlpcWpKSmJJqnJAMMQ4xmIg4QE0DqEuNzE5ByK3G0hoMTCoIMmlliQC9SdaxWf7uniWpOaGFqcWhSSmF4PVPwUSkQwM5ljUA5X7JCal5sQnlqflpSUZ5ZSXllSUG2WUlJaXJWVWJpekFgI1l5ak6VpYGxqbGBmaW1qYuM0XSwK7pOQ+L4hiYSjaJZ76e4b/z43CbA+v3b84g7hgRQdJBTmZxSUGBgs4oIHACJVgRFPI+WmORXHowReOWbqc+yYek/14m/8E1+/cQ8kB/0SMDjj5/2iRfOXtdb7XtuZV46Gg+7xvnx3/IsjtPzPafWVHytTzJz69P3BbfMHzYnnx618Ewl5frth67rLkNn8360wAUEsHCKES2L9wAQAAPgIAAFBLAQIUAxQACAAIAPF+V1TEckU4GQAAABcAAAAKACAAAAAAAAAAAACkgQAAAABwcnVlYmEudHh0VVQNAAdGnxZiSJ8WYkafFmJ1eAsAAQT1AQAABBQAAABQSwECFAMUAAgACADxfldUoRLYv3ABAAA+AgAAFQAgAAAAAAAAAAAApIFxAAAAX19NQUNPU1gvLl9wcnVlYmEudHh0VVQNAAdGnxZiSJ8WYk+fFmJ1eAsAAQT1AQAABBQAAABQSwUGAAAAAAIAAgC7AAAARAIAAAAA
--ejjeeffe1--

But we get the following error.

Exception caught by adapter framework: STATUS_CODE_NOT_OK- 400 Bad Request

This is the configuration used for the HTTP_AAE adapter.

We are sending the file in base64 in the body formdata.

What suggestions can you give us with the above.

Regards.

0 Kudos

Hi Muniyappan,

After making the suggested changes, the service responded correctly.

Thank you so much.

Regards,

Harinath

0 Kudos

Hi stefan.grube friman.ramos muniyappan.marasamy ,

While sending the Rest formdata, I am also experiencing the same issue.

We are able to post the data via Postman, and the following are the API logs for Postman

In the receiver HTTP communication channel, the following configuration is used.

The next java mapping sends this information. The import mode of the .xml file is "NORMAL" which sends it through the form data service.

package com.test.sap.pi.file;

import java.io.*;
import java.net.HttpURLConnection;
import java.util.Map;

import com.sap.aii.mapping.api.StreamTransformation;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.Reader;
import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.*;
import java.io.*;

import com.sap.aii.mapping.api.StreamTransformationException;

import com.sap.aii.mapping.api.TransformationInput;

import com.sap.aii.mapping.api.TransformationOutput;
@SuppressWarnings("deprecation")

public class CreateForm implements StreamTransformation {

     private String boundary;
     private String boundary2;

     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";
         boundary2 = "--ejjeeffe1--";

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

        // body =  boundary + LINE_FEED ;

//        body.concat(boundary);

         addFormField("import_mode","NORMAL" );

        // addFormField("Filename","PriceFeed.xml" );

  

         body =body + boundary;

  

         body = body + LINE_FEED + "Content-Disposition: form-data; name=\"" + "file" +

         "\"" + "; " + "filename=\"" + "PriceFeed.xml" + "\"" +

          LINE_FEED + "Content-Type: text/xml"  + 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 + boundary2;

  try {

  arg1.write(endchar.getBytes());

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  public void setParameter1(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 =  boundary + LINE_FEED + "Content-Disposition: form-data; name=\"" + name + "\""

+ LINE_FEED + LINE_FEED

    			    + value + LINE_FEED;

    }

	public void setParameter(Map param) {
		// TODO Auto-generated method stub
		
	}

}<br>

I receive the following response after submitting

The SWC was removed from the ICO.

Could you please suggest a solution to this scenario?

Your comments would be greatly appreciated,

Regards,

Harinath

Muniyappan
Active Contributor
0 Kudos

Did you check stefans reply? May be you are missing

String endchar = LINE_FEED + LINE_FEED + boundary;