Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_grube
Active Contributor
14,109


Some years ago I wrote a blog about emails with body and attachment with help of the MailPackage structure:

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

 

In this blog, I will present another solution which does not use MailPackage and I show also how to add binary payloads to an email.


Note: The payload of the XI message will be the email attachment. If you want an attachment of the XI message to be used as an email attachment instead, you have to adjust this sample code.


 

Meanwhile, there are many blogs available that show the use of the mail adapter and module configuration. However, using a Java mapping to create the whole MIME stream is the most flexible way to create a mail exactly in the way that it should look like.

 

The following code should show the basics of the MIME creation, feel free to use and enhance it to your needs:

 












Java Mapping to create MIME parts of an email

package sample;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.xml.bind.DatatypeConverter;
import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;

public class MyBinaryMessageAsAttachment extends AbstractTransformation {

String attachmentName = "file.pdf";
String boundary = "-" + "-" + "AaZz"; //
String contentType = "multipart/mixed; boundary=\"" + boundary + "\"";
String mailContent = "This is a sample file";
String CRLF = "\r\n";

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

InputStream in = arg0.getInputPayload().getInputStream();
OutputStream out = arg1.getOutputPayload().getOutputStream();
try {
// create the declaration of the MIME parts
//First part
String output = "-" + "-" + boundary + CRLF
+ "Content-Type: text/plain; charset=UTF-8" + CRLF
+ "Content-Disposition: inline" + CRLF + CRLF
+ mailContent // this should be some more useful text
+ CRLF + CRLF

//Second part
+ "-" + "-" + boundary + CRLF
+ "Content-Transfer-Encoding: base64" + CRLF
+ "Content-Type: application/pdf; name="
+ attachmentName + CRLF
+ "Content-Disposition: attachment; filename="
+ attachmentName + CRLF + CRLF;
out.write(output.getBytes());

// convert InputStream to Byte array
byte[] input = new byte[in.available()];
in.read(input);

// convert payload to base64
output = DatatypeConverter.printBase64Binary(input);

// split lines after 76 rows
output = addLinefeeds(output);
out.write(output.getBytes());

// last boundary
output = CRLF + CRLF + "-" + "-" + boundary + "-" + "-" + CRLF;
out.write(output.getBytes());

// set content type to message header
arg1.getOutputHeader().setContentType(contentType);
} catch (IOException e) {
throw new StreamTransformationException(e.getMessage());
}

}




public String addLinefeeds(String str) {

StringBuffer result = new StringBuffer(str);
int n = 76; // split by 76 characters (maximum of numbers in lines)
int l = str.length();
int i = n;

while (l > n) {
result.insert(i, CRLF);
i = i + n + 2;
l = l - n;
}
return result.toString();
}

}



 

The Java Mapping will create two MIME parts. The first part is plain text, the second part is a binary, therefore we encode it to base64 and divide it into lines of no more than 76 characters each (which is the allowed maximum according to MIME protocol). The result will look like this:

 












Sample output of Java mapping


----AaZz

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

Content-Disposition: inline

 

 

This is a sample file

 

 

----AaZz

Content-Transfer-Encoding: base64

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

Content-Disposition: attachment; filename=file.pdf

 

 

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPGNmZGk6Q29tcHJvYmFudGUg

cnRlPSIxNjA4Ni4xMyI+PC9jZmRpOlRyYXNsYWRvPjwvY2ZkaTpUcmFzbGFkb3M+PC9jZmRpOklt

cHVlc3Rvcz48Y2ZkaTpDb21wbGVtZW50bz48L2NmZGk6Q29tcGxlbWVudG8+PC9jZmRpOkNvbXBy

b2JhbnRlPg==

 

 

----AaZz--


 

This scenario requires special settings of the Mail adapter channel.

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

 

 

If you want to know, how the MIME parameters Content-Type and Content-Transfer-Encoding work, and which other parameters can be used, then look into RFC 1341 about MIME (Multipurpose Internet Mail Extensions): http://www.w3.org/Protocols/rfc1341/0_TableOfContents.html

24 Comments
rhviana
Active Contributor
0 Kudos

Nice Blog Stefan,

This really help me in the past - 2010 to develop the B2B solution for SAP GRC NF-e Brazil product.

Thanks for that, also I created in the past one blog releted with two types of attachments - XML and PDF file.

Multiples content Email - File Attached and body text

See you around,

Viana.

Former Member
0 Kudos

Hi Stefan,

Thank you so much for the blog :smile: it was very useful for me as i am a begginer in PI .

anupam_ghosh2
Active Contributor
0 Kudos

Hi Stefan,

                    The pdf content is being encoded using base 64 encoding.

The receiver has top decode the same I guess or he/she can read it just like PDF.

Regards

Anupam

stefan_grube
Active Contributor
0 Kudos

The decoding will be done by the e-mail client. So the receiver will see the PDF directly.

former_member190293
Active Contributor

Hi Stefan!

Thanks for another nice blog!

One thing: wouldn't you correct the phrase "into lines with 76 rows" in your record. I guess it should be something like "into lines with length of 76 symbols" there :smile: .

Regards, Evgeniy.

anupam_ghosh2
Active Contributor
0 Kudos

awesome thanks a lot Stefan . this helped me a lot.

stefan_grube
Active Contributor

Good point. The RFC1341 says: "The output stream (encoded bytes) must be represented in lines of no more than 76 characters each." I corrected the phrase in my blog accordingly.

ravicarpenter
Active Participant
0 Kudos

Thanks Stefan,

The example was useful to me.

0 Kudos
Hey stefan,

My requirement is to have a pdf attachment (xHTML) and a  static text in the body all the time. The interface is built as much as populating XHTML via XSLT and PDF renderer in an adapter module before calling the mail adapter.i am trying to add the body now.

However, without deviating , i used your code and deployed it successfully and tried to run a simple test.I do get the output just a body without any attachments if i go by the channel config as well.

Would you be able to shed any light on my requirement and generating an attchment and body via your code?

 

Many thanks,

Sam

 

 
0 Kudos
Hey Stefan, I used this code to see if an attachment is being created.While the code is being deployed and works, i do not see an attachment and the output you have shown is right but all of it comes in the body.I have made the channel settings exactly as you had mentioned.

 

Can you please suggest how to get the attachment and the body text or am i doing anything wrong?
0 Kudos
Hey stefan,

 

UPDATE: the code you have posted works fine.There was a final '-' missing for some reason in the final boundary condition and now its works perfect.

 

MANY thanks once again to show this way forward.
0 Kudos
Hello Stefan,

This is really useful post. I was able to get it working but both attachment contents and mail body are in the body.

 

Hello Shyam,

I am getting the same problem.

Can you please share what you did to fix this?

 
stefan_grube
Active Contributor
0 Kudos
The font which is used for the Java code does not show the two minus (--) characters good, it appears as one character.

Make sure that all boundaries start with two minus characters and the last boundary also ends with two minus characters.

I changed the code to make it more obvious.
Former Member
0 Kudos
Hi Stefan,

For a text file attachment can you share the lines where we need to modify the code?

 

Thanks

Dave

 
stefan_grube
Active Contributor
0 Kudos
Hi Dave,

for a text file, you have to change following lines:
String attachmentName = "file.txt";

+ "Content-Type: text/plain; name="

For any other file type, you have to choose file name and content-type accordingly.

Regards

Stefan

 
Former Member
0 Kudos
Hello Stefan,

Thanks for this excellent blog.

When i am following this blog, I am getting an email with attachment with the given file name in the java code (like file.pdf). But, it is just a dummy attachment with size around 600 bytes. The actual attachment (in my case is 30KB) is not getting passed on to the email. Any idea why?

Where exactly are you reading the attachment from the sender/source and passing it on to the email receiver?

Am i missing something here?

Thanks

Chandra
Former Member
0 Kudos
Thanks Stefan
stefan_grube
Active Contributor
0 Kudos
Hi Chandra,

My Java code uses the main payload of the XI message as the email attachment.

If you want to have an XI message attachment as the email attachment, you have to change the code accordingly. It is tricky to read the attachment.

Check the current API here (the link might change later):

https://help.sap.com/doc/2f39047ed6b141cb83658041d2d4e029/7.5.10/en-US/PI/index.html?com/sap/aii/map...

 

Regards

Stefan

 

 
Former Member
0 Kudos
Hi Stefan,

I tried your code. i can see the attachment in email but when i try to open it, its giving me Error.

"Adobe Reader could not open "file.pdf" because it is either not a supported file type or because the file has been damaged."

kindly let me know what could be the reason for this issue. I even tried generating attachment through udf there also am getting same error.

Thanks,

Sonam Ramsinghani
ericavieira
Explorer
0 Kudos
Hello Stefan,

 

I have a pretty similar code in my interface, however the mail receiver adapter is using startTLS = true and it is unconfiguring the email.

The attachment is coming in the body of mail.

If I remove the startTLS code everything is going ok.

 

Do you know why?

Regards

Erica
0 Kudos
Hi Stefan,

My client ask me about a printable version of email, readed from a 365 account with a sender IMAP channel.

The emails reads are MIME nested multipart, with HTML and bitmaps in body, and binary attachments.

The channel was configured to read the emails and attachments, working fine, then sent it to ABAP with a inbound proxy with attachments. All sounds good but my client ask me to save a binary printable version of original email, an pdf or eml file, for documenting/auditing purpose.

 

Can be possible to read a printable/binary version of original email in PI?

 

Best regards

 
JaySchwendemann
Active Contributor
0 Kudos
Will you be able to share details if you tackled this (I'm supposing you are currently looking for a solution, still).
anupam_ghosh2
Active Contributor
0 Kudos

Hi Stefan,

Thank you for sharing this important blog.

Tried this code for zip files with minor changes such as "Content-Type: application/zip;". However attached zip file on email is not readable by zip programs after download. Is BASE 64 encoding required for zip files or can be avoided, this is where I am little confused.

ZIP files are binary files as far as my knowledge on the topic.

Please kindly share your views on the same.

Regards

Anupam

 

stefan_grube
Active Contributor
0 Kudos
i recommend

Content-Transfer-Encoding: base64

for any binary like zip, pdf, jpg and so on.

if the zip file is not readable, ensure that the MIME part is precisely according to the MIMI protocol.

For example, the last boundary needs additional two leading hyphens '--'
Labels in this area