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> 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”<MyName@MyCompany.com></From> <To>”You”<YourName@YourCompany.com></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 "A00",2,3,4,5,6 "N90",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\”<MyName@MyCompany.com>”; String mailReceiver = “\”You\”<YourName@YourCompany.com>”; 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(“&”, “&”); sbuf = sbuf.replaceAll(“\””, “"”); sbuf = sbuf.replaceAll(“‘”, “'”); sbuf = sbuf.replaceAll(“<“, “<”); sbuf = sbuf.replaceAll(“>”, “>”); 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 … |
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
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
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
Soyou cannot work on the original mail structure in a sender mail adapter.
Regards
Stefan
Could you shed some light as to how you used Stefan's code in a UDF to get the same result please?
Thanks
Thanks Rahul
Regards
Stefan
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