Skip to Content
Author's profile photo Stefan Grube

XI Mail Adapter: An approach for sending emails with attachment with help of Java mapping

Update 10.03.2016: This blog talks about the use of the Mail Package of the Mail Adapter. It is still possible to use it, but not recommended.

I have created a new blog for showing, how to achieve the same without using the Mail Package: Create email with body and attachments for binary payload with Java mapping

Let us assume we have a simple message without attachment. Now we want to create an email with standard text and the message as an attachment. The first question is: How does an email with attachment look like? For this reason, we can send an email and watch the structure.
The email header is omitted here:

Email in raw view

From: MyAddress@company.com

Date: Tue, 17 Apr 2007 13:57:38 +0200 (MEST)

Message-ID: <18992192.1176811058601.JavaMail.D002945@WDFN00174410A>

To: YourAddress@company.com

Subject: My Test

Mime-Version: 1.0

Content-Type: multipart/mixed; boundary=”—-=_Part_0_138093.1176811058539″

X-SAP: out

_Part_0_138093.1176811058539

Content-Type: text/plain; charset=us-ascii

Content-Transfer-Encoding: 7bit

Test

_Part_0_138093.1176811058539

Content-Type: application/xml; name=DOM_IN.xml

Content-Transfer-Encoding: 7bit

Content-Disposition: attachment; filename=DOM_IN.xml

“A00”,2,3,4,5,6

“N90”,2,3,4,5,6

_Part_0_138093.1176811058539–

Here we can see that an email with attachments has different parts. The Content-Type multipart starts a sequence of parts which are divided by a boundary. The first part is a plain text; the second part is an xml message. The Content-Type and Content-Disposition is declared for each part separately.

Now we try to use the mail package to create a mail like this. The mail package structure can be downloaded in SAP Note 748024  (https://service.sap.com/sap/support/notes/748024) (User required)

Mail Package with multipart

<?xml version=”1.0″ encoding=”UTF-8″?>

  <ns:Mail xmlns:ns=”http://sap.com/xi/XI/Mail/30“>

    <Subject>OrderResponse</Subject>

  <From>”Me”&lt;MyName@MyCompany.com&gt;</From>

  <To>”You”&lt;YourName@YourCompany.com&gt;</To>

  <Content_Type>multipart/mixed; boundary=”–AaZz”</Content_Type>

  <Content>—-AaZz

Content-Type: text/plain; charset=UTF-8

Content-Disposition: inline

This is a sample file

—-AaZz

Content-Type: application/csv; name=file.csv

Content-Disposition: attachment; filename=file.csv

&quot;A00&quot;,2,3,4,5,6

&quot;N90&quot;,2,3,4,5,6

—-AaZz–

</Content>

  </ns:Mail>

The Java Mapping to create the Mail Package structure looks like this:

Java Mapping to create Mail Package

package sample;

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

import java.io.*;

public class MyMessageAsAttachment extends AbstractTransformation {

  // Main class for local test

  public static void main(String[] args) {

    try {

      InputStream in = new FileInputStream(new File(“in.xml”));

      OutputStream out = new FileOutputStream(new File(“out.xml”));

      MyMessageAsAttachment myMapping = new MyMessageAsAttachment();

      myMapping.execute(in, out);

      } catch (Exception e) {

        e.getMessage();

      }

  }

  public void transform(TransformationInput arg0, TransformationOutput arg1)  throws StreamTransformationException {

            this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());

  }

  public void execute(InputStream in, OutputStream out) throws StreamTransformationException {

    String mailSubject = “OrderResponse”;

    String mailSender = “\”Me\”&lt;MyName@MyCompany.com&gt;”;

    String mailReceiver = “\”You\”&lt;YourName@YourCompany.com&gt;”;

    String attachmentName = “file.xml”;

    String boundary = “–AaZz”;

    String mailContent = “This is a sample file”;

    String CRLF = “\r\n”;

    try {

      // create XML structure of mail package

      String output =

            “<?xml version=\”1.0\” encoding=\”UTF-8\”?>”

        + “<ns:Mail xmlns:ns=\”http://sap.com/xi/XI/Mail/30\”>”

        + “<Subject>” + mailSubject + “</Subject>”

        + “<From>” + mailSender + “</From>”

        + “<To>” + mailReceiver + “</To>”

        + “<Content_Type>multipart/mixed; boundary=\””

        + boundary

        + “\”</Content_Type>”

        + “<Content>”;

        out.write(output.getBytes());

      // create the declaration of the MIME parts

      //First part

      output = “–” + boundary + CRLF

                + “Content-Type: text/plain; charset=UTF-8” + CRLF

                + “Content-Disposition: inline” + CRLF + CRLF

                + mailContent + CRLF + CRLF

      //Second part

                + “–” + boundary + CRLF

                + “Content-Type: application/xml; name=” + attachmentName + CRLF

                + “Content-Disposition: attachment; filename=” + attachmentName + CRLF + CRLF;

      out.write(output.getBytes());

      //Source is taken as attachment

      copySource(in, out);

      // last boundary

      output = CRLF + CRLF +”–” + boundary + “–” + CRLF;

      out.write(output.getBytes());

      // finish mail package

      out.write(“</Content></ns:Mail>”.getBytes());

    } catch (IOException e) {

      throw new StreamTransformationException(e.getMessage());

    }

  }

  protected static void copySource(InputStream in, OutputStream out) throws IOException {

    byte[] buf = new byte[in.available()];

    in.read(buf);

    String sbuf = new String(buf);

    // replace all control characters with escape sequences

    sbuf = sbuf.replaceAll(“&”, “&amp;”);

    sbuf = sbuf.replaceAll(“\””, “&quot;”);

    sbuf = sbuf.replaceAll(“‘”, “&apos;”);

    sbuf = sbuf.replaceAll(“<“, “&lt;”);

    sbuf = sbuf.replaceAll(“>”, “&gt;”);

    out.write(sbuf.getBytes(“UTF-8”));

  }

}

It is very important that in Communication Channell if type Mail, the mail attribute Use Mail Package is checked, Content Encoding is set to None and Keep Attachments is not checked.

Note: This approach works only for text based payload, like XML, HTML. For binary payloads, like PDF or ZIP, you can use Content-Transfer-Encoding: base64. That means the payload needs to be encoded in base64. It should look like this:

—-AaZz

Content-Type: application/pdf; name=”Invoice.pdf”

Content-Transfer-Encoding: base64

Content-Disposition: attachment; filename=”Invoice.pdf”

5/IcVrU0TLcKKKKYgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC

iiigAooooAa6B0ZT0YYrm4o8iW3fqQV/EVvNdxpcCFshiM57Vk6inkagWHAkAYfXvTRlV2uuhmq5

fS5oj1ikWQfjwf1xU1j/AKlar3n7q5kx9yVc/n/9eiNv9HQe5pp2Jqe9FGtHUwqrayeZGCeo4NWV

rS9zCKtoRMNrEU5TSzAcNTFquhFrMsIcgis65XyrvcOjc/41eU4qDUE3RBu6n9KFozXdApqRWqtG

Assigned Tags

      9 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member
      Nice blog and very helpful to get around some quirks in the mail adapter configuration. I do have one issue though. In your example you do not set the content-transfer-encoding directly. In your given output example the transfer-encoding is set to 7 bit. If I set the transfer-encoding to None in the adapter configuration my final transfer-encoding for the mail envelope is always set to binary. Are there any special parameters to set the encoding?
      Author's profile photo Stefan Grube
      Stefan Grube
      Blog Post Author
      I have not set content-transfer-encding in this example and it is set automatically to 7bit.
      If you want to have a different value, like base64, you have to provide the attachment in this format by your own, that means you need to use base64 conversion in the Java mapping.

      The same is for the content encoding (charset). If you use another chaset as UTF-8, your Java mapping has to change the encoding.

      Regards
      Stefan

      Author's profile photo Former Member
      Former Member
      It is great Blog...really thanks

      i did the same and i was able to get both the emial and the attachment. but i have a bigger requirements and i am not sure if someone can help.

      my scenario is that i am picking a flat file using file adapter, and then using java mapping (as this blog) and using mail package i need to send an email with an Excel attachment (xls). but that xls attachment is not the whole body...instead i just need to loop over some feilds and create the result in the resulted excel attachment...!!

      Does anyboy have any idea how to convert the XI payload and get some portion of its data and convert it to Excel ?

      Please help.

      Thaks
      Tarek

      Author's profile photo Stefan Grube
      Stefan Grube
      Blog Post Author
      Check this blog:
      eMail Report as Attachment (Excel/Word)

      As that blog works with xslt, it requires an XML file for input, but it shows the principles of xls and you could use Java code instead of XSLT to read the flat file and create the xls output.

      Regards
      Stefan

      Author's profile photo Stefan Grube
      Stefan Grube
      Blog Post Author
      The sender mail adapter always creates the XI message with main payload and attachments before a customer module or Java mapping is excuted.
      Soyou cannot work on the original mail structure in a sender mail adapter.

      Regards
      Stefan

      Author's profile photo Johan Delport
      Johan Delport
      Hi Nasif,

      Could you shed some light as to how you used Stefan's code in a UDF to get the same result please?

      Thanks

      Author's profile photo Rahul Thunoli
      Rahul Thunoli
      This blog worked very well for me , though i was using xslt mapping . Thank you very much .  I think the key thing was to identify how the email header looked like . Could you tell me from where do you get to see the email header structure after you send out a mail .

      Thanks Rahul

      Author's profile photo Stefan Grube
      Stefan Grube
      Blog Post Author
      I used a googlemail account for this. In goolemail you have an option "show original", which allows you to see the MIME headers.

      Regards
      Stefan

      Author's profile photo Former Member
      Former Member

      Hi Stefan,

      I am having requirement in PI 7.3 to send email attachment with dynamic name.

      Can you please let me know if I can set content-disposition dynamically without mail package,without adapter module in PI 7.3

      Regards,

      Akshay