Skip to Content

SAP PI/PO- REST to File - Download file from URL which comes in a field

Hello Experts,

I am on PO 7.5 and working on a REST to File scenario.

Requirement: I need to download a file from a URL .The URL is sent in a field through the REST Call. See below example.

Example:

<Record>

FileName> TestFile1.pdf

URL>www.test.com/TestFile1.pdf

</Record>

<Record>

FileName> TestFile2.pdf

URL> www.test.com/TestFile2.pdf

</Record>

Desired Result: Download the 2 files (TestFile1.pdf and TestFile2.pdf) from the URL's from the URL field and drop it off in an FTP/SFTP server.

I am not a java expert/or an expert with module configuration. Can we do this using an UDF in the graphical mapping.

I see the support attachments option in the REST sender attachment. I am not sure if that is helpful for my scenario.

I checked all the blogs and I was not able to find one that suits my requirement.

Can please you guide me through the configuration process.

Thanks,

Chan

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

4 Answers

  • Hello Har` Chan,
    As your source XML message contains multiple records, so the link to download the files will be multiple and dynamic.

    For a static url, you can get the files using a GET operation of the REST adapter.
    Or you can also implement SOAP-AXIS , where you can use the TASK(Axis) protocol and the HTTPGetter class as connection parameter.You also need to use the parameter - enableREST as true.

    But your source XML has multiple links, so I would say you can create a Java class with a method to get the file from url and save it in a string.

    In your Java mapping method you can pass the number of records and that many times you can all the method to get the files.

    you can call this Java method in your mapping to get all the files and append to a single file. Then you can use a 2nd step mapping to split the entire xml into multiple messages and can produce multiple files at target.
    Though the above design is not a efficient one. In this way it will be hard to capture the each of the source file name. But you can still populate this using Dynamic configuration UDF.

    Moreover, you have to download pdf files which is a binary non-xml file. So it will be too complex with the above approach

    Thanks

    Sugata

    Add comment
    10|10000 characters needed characters exceeded

  • 4 days ago

    Hello Chan,

    Nice question and interesting requirement!

    step 1) read the url from the request payload (udf cannot be used here and we need to write java mapping inside message mapping)

    step 2) Get the PDF file in byte array form from the url (make sure you imported the certificates) check if the url requires basic auth or no auth.

    Step 3) add attachment inside java mapping code.

    Paste the below code in Attributes and methods tab of Request message mapping.

    StringBuilder sb = new StringBuilder("");
    boolean flag_all_ok = false;
    
    
    @Override //Overriding the transform method of the Process and don't declare anything between override and the transform method
    public void transform(TransformationInput In, TransformationOutput Out) throws StreamTransformationException {
     super.transform(In, Out);
    
    
     String[] pdfURL = this.getFileURL(In);
    
    
     for (int i = 0; i < pdfURL.length; i++) {
      byte[] pdf = this.getPdfFile(pdfURL[i]);
    
    
      OutputAttachments OA = Out.getOutputAttachments();
    
    
      Attachment att = OA.create("file" + (i + 1) + ".pdf", "application/pdf", pdf);
    
    
      OA.setAttachment(att);
     }
    
    
    }
    public String[] getFileURL(TransformationInput Ti) {
    
    
     String[] fURL = new String[2];
     //reading request mapping payload
     try {
      //Reading Response payload into a String from InputStream
    
    
      InputStream in = Ti.getInputPayload().getInputStream();
      InputStreamReader isr = new InputStreamReader( in );
      Reader reader = new BufferedReader(isr);
      int ch;
      while ((ch = in .read()) > -1) {
       sb.append((char) ch);
      }
      reader.close();
      String result = sb.toString();
      //now the Input Stream contains the data before mapping and we need the url part  <Url>https://sapowernetworks.sharepoint.com/sites/FieldServicesCustomerPrograms/Field%20Photos/2018-09-06/2018-09-06-095745-MitchellOgilvy.jpg</Url>
      fURL[0] = result.substring(result.indexOf("<URL>") + 5, result.indexOf("</URL>"));
      //getting second URL
      int startPointForNextURL = result.indexOf("</URL>") + 6;
      fURL[1] = result.substring(result.indexOf("<URL>", startPointForNextURL) + 5, result.indexOf("</URL>", startPointForNextURL));
      //We need only the relative path of the image to access it so removing the common part of URL 
    
    
     } catch (Exception e) {
    
    
     }
     return fURL;
    }
    
    
    public byte[] getPdfFile(String webUrl) {
    
    
     byte[] bytes = new byte[1024];
     try {
    
    
      URL url = new URL(webUrl);
      URLConnection connection = url.openConnection();
      HttpURLConnection httpConn = (HttpURLConnection) connection;
    
    
      //Specifying Http Operation and Header parameters for Authorization , Access token is being used here
      //	httpConn.setRequestMethod("GET");		//In case the url works on GET or POST
      //	httpConn.setRequestProperty("Authorization", "Bearer " + accessToken); // In case you need basic authentication for access
    
    
      String httpResponseStr = "";
    
    
      //making the http call
      InputStream is = null;
      if (httpConn.getResponseCode() == 200) {
       is = httpConn.getInputStream();
       flag_all_ok = true;
      } else {
       is = httpConn.getErrorStream();
      }
    
    
      //*****reading inputStream to a Byte array this is really important and needs to be done correctly********
      //you cannot read a binary file to a String as the binary content gets curropted.
    
    
    
    
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
    
      int read = 0;
      while ((read = is.read(bytes, 0, bytes.length)) != -1) {
       baos.write(bytes, 0, read);
      }
      baos.flush();
    
    
      bytes = baos.toByteArray();
     } catch (Exception e) {}
    
    
     return bytes;
    
    
    }
    

    Here you go!

    The file receiver channel should be fine tuned for multiple attachments for which i would not go into the details.

    Regards

    Vinay

    Add comment
    10|10000 characters needed characters exceeded

  • 2 days ago

    Was it able to help you?

    Add comment
    10|10000 characters needed characters exceeded

  • Hello,

    I recently created a post explaining how to download a file from amazon, it seems to be a scenario close to what you presented.

    Or try using the FormatConversionBean module adapter that makes encoded/decoded files ... https://blogs.sap.com/2015/03/25/formatconversionbean-one-bean-to-rule-them-all/

    Add comment
    10|10000 characters needed characters exceeded