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 ... |