cancel
Showing results for 
Search instead for 
Did you mean: 

Send POST HTTP REST Documment JSON and Attachment File

0 Kudos

Hello friends of the SAP community, I hope you can help me !!

I need to send a form to a REST web service whose parameters are a JSON document and a PDF file attached.

this is an example of web form that sends the POST.

I want to build an asynchronous scenario which is PROXY -> PI -> REST

But want to configure REST Receiver Communication channel does not allow me to put attachments.

I could recreate an example of sending this data with the tool SOAPUI but I can not work with PI.

Accepted Solutions (1)

Accepted Solutions (1)

0 Kudos

Add New Info:

Try changing the REST Receiver Communication Channel for a new scenario.

PROXY -> PI -> HTTP_AAE (this allows me to an attachment)

And with a custom module it allows me to convert the XML message in JSON but I have errors in the execution of the interface.

Even I configured in Content-Type as multipart/form in the section Advanced Tab

Payload Sent:

The message is not delivered and the response received is:

<SAP:AdditionalText>com.sap.aii.adapter.http.api.HttpAdapterException: ERROR_SENDING_HTTP_REQUEST-Message Processing Failed. Reason : com.sap.httpclient.exception.ProtocolException: Data is not repeatable.</SAP:AdditionalText>

if monitoring the communication channel error I can see the message content in JSON format

0 Kudos

Hi All,

I have resolved the issue, by applying a mapping program JAVA, which converts the content-type of the two parts of the message body, adding the data I needed.

To do this, I build on the following Blogs:

HTML MultiPart Form upload using HTTP Plain adapter with Java mapping

Create email with body and attachments for binary payload with Java mapping

And here's the solution:

File CreateForm.java

package com.sap.map.multipart;

import java.io.*;

import java.util.Collection;

import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

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

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

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

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

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

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

public class CreateForm extends AbstractTransformation {

    private static final String LINE_FEED = "\r\n";

    private String contentType1;

    private String contentType2;

  @SuppressWarnings("unchecked")

  public void transform (TransformationInput in, TransformationOutput out)

  throws StreamTransformationException {

  AbstractTrace trace = getTrace();

  String json = new String();

  InputStream ins = in.getInputPayload().getInputStream();

  try{

  //***************************************************************

  //Get document XML from input stream.

  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

  DocumentBuilder builder = factory.newDocumentBuilder();

  Document doc = builder.parse(ins);

  //***************************************************************

  //***************************************************************

  //Convertir XML a JSON - y Escribir nuevo Payload con content-type editado

  //***************************************************************

         //Instanciamos la clase para convertir el Payload

  ParseDocument pDoc = new ParseDocument();

  //Guardamos el nuevo Payload en variable String

         json = pDoc.ConvertDocumentXML2JSON(doc);

  //Editamos un nuevo content-type para el encabezado del Payload

          contentType2 = "text/plain;charset=us-ascii" + LINE_FEED

            + "content-transfer-encoding:7bit" + LINE_FEED

            + "content-disposition:form-data;name=\"document\"";

           //Grabamos el nuevo contentype en el Header del Payload

         out.getOutputHeader().setContentType(contentType2);

        //Convertimos en Bytes el String nuevo y lo grabamos en la salida

         byte[] message = json.getBytes("UTF-8");

         //Escribimo el Output Pay-load

  out.getOutputPayload().getOutputStream().write(message);

  //***************************************************************

  //***************************************************************

  //Reescribimos el Header del Adjunto y grabamos el nuevo

  //***************************************************************

         //Se obtienen los ContentID de los Adjuntos

  Collection<String> contId = in.getInputAttachments().getAllContentIds(false);

         String contentId = null;

         //Iteramos para obtener el String del ContentID

         for (Iterator iterator = contId.iterator(); iterator.hasNext();) {

          contentId = (String) iterator.next();

         }

         //Creamos un Objeto Adjunto de entrada y lo tomamos con el ContentID obtenido

         Attachment adjuntoIn = in.getInputAttachments().getAttachment(contentId);

         //Guardamos en Variables los 3 parámetros del adjunto de entrada

         //1) ContentID ya lo teniamos

         //2) el contenido del archivo en Bytes[]

         byte[] content = adjuntoIn.getContent();

         //3) el content-type del header del adjunto

         contentType1 = adjuntoIn.getContentType();

         //Editamos el content-type del header del adjunto al valor nuevo deseado

         contentType1 = contentType1 + LINE_FEED

              + "content-transfer-encoding:binary" + LINE_FEED

              + "content-disposition:form-data;name=\"" + contentId +"\";filename=\"" + contentId + "\"";

         //Eliminamos de la Salida el Adjunto que teniamos

         out.getOutputAttachments().removeAttachment(contentId);

         //Creamos un nuevo adjunto con los valores deseados

         Attachment adjuntoOut = out.getOutputAttachments().create(contentId, contentType1, content);

         //Seteamos el nuevo adjunto como adjunto de Salida

         out.getOutputAttachments().setAttachment(adjuntoOut);

  //***************************************************************

  //***************************************************************

  } catch (Exception e) {

  trace.addDebugMessage(e.getMessage());

  }

  }

  }

I used a helper class to convert the XML document into JSON:

File ParseDocument.java

package com.sap.map.multipart;

import org.w3c.dom.CharacterData;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.Document;

import org.w3c.dom.NodeList;

public class ParseDocument {

  public String ConvertDocumentXML2JSON(Document doc) {

  String xmlParse = "";

  try {

  doc.getDocumentElement().normalize();

  //Get the node List that contains the node "document"...

  Element nodoRaiz = null;

  NodeList listaNodos = null;

  Node nodo = null;

  Element elem = null;

  xmlParse = "{ ";

  NodeList documentNode = doc.getElementsByTagName("n0:Document");

  nodoRaiz = (Element) documentNode.item(0);

  listaNodos = nodoRaiz.getChildNodes();

  for (int i = 0; i < listaNodos.getLength(); i++) {

  nodo = listaNodos.item(i);

  if (nodo instanceof Element) {

            elem = (Element) nodo;

    if (xmlParse != "{ "){xmlParse = xmlParse + ", ";}

    xmlParse = xmlParse +"\""

  +elem.getNodeName()

  +"\": \""

  +getCharacterDataFromElement(elem)

  + "\"";

  }

  }

  xmlParse = xmlParse + " }";

  } catch (Exception e) {

  System.out.println(e.getMessage());

  }

  return xmlParse;

  }

  public static String getCharacterDataFromElement(Element e) {

  String texto = "";

  Node child = e.getFirstChild();

  if (child instanceof CharacterData) {

  CharacterData cd = (CharacterData) child;

  texto = cd.getData();

  return texto;

  }

  return "";

  }

}

Answers (1)

Answers (1)

0 Kudos

Hello have got a similar issue ...so here initail content you have written in hear ...json paylaod in body and for attachment have you used checkbox to keep attachment