This blog is mainly based on the detailed steps of developing a e-mail sending functionality which shows how to use the connectivity service APIs to send e-mail. For any application that is applicable for a particular business operations, sending email to a group of users is a common feature that needs to be incorporated in the UI either as a button feature or hyperlink.
The example is a stand alone application that provides a simple User Interface to compose an e-mail message and send it.The e-mail connectivity functionality allows us to send electronic mail messages from our Web applications using e-mail providers that are accessible on the Internet, such as Google Mail (Gmail).
To send and fetch e-mail, the following configurations are required:
Most of the steps are just the same as mentioned in SAP HANA Cloud Platform documentation. Apart from that, I have tried to cover few troubleshooting steps which I have experienced while developing it. All these information are available in bits and pieces and I have tried to consolidate them in a single blog. So following this steps will actually help us to create a stand alone email sending application which can be consumed by the mail sending feature in any Business Applications in HCP.
JavaMail API
The JavaMail API provides classes that model a mail system. The javax.mail
package defines classes that are common to all mail systems. The javax.mail.internet
package defines classes that are specific to mail systems based on internet standards such as MIME, SMTP, POP3, and IMAP. The JavaMail API includes the javax.mail
package and sub-packages.
Mail Session
A servlet can obtain a mail session resource using resource injection or a JNDI lookup. The properties of the mail session are specified by a mail destination configuration. So that the resource is linked to this configuration, the names of the destination configuration and mail session resource must be the same.
@Resource(name = "mail/Session") private javax.mail.Session mailSession;
<resource-ref> <res-ref-name>mail/Session</res-ref-name> <res-type>javax.mail.Session</res-type> </resource-ref>
An initial JNDI context can be obtained by creating a javax.naming.InitialContext object. We can then consume the resource by looking up the naming environment through the InitialContext, as follows:
InitialContext ctx = new InitialContext(); Session mailSession = (Session)ctx.lookup("java:comp/env/mail/Session");
Sending E-Mail
With the javax.mail.Session object we have retrieved, we can use the JavaMail API to create a MimeMessage object with its constituent parts (instances ofMimeMultipart and MimeBodyPart). The message can then be sent using the send method from the Transport class:
Transport transport = mailSession.getTransport();
transport.connect();
MimeMessage mimeMessage = new MimeMessage(mailSession);
...
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
transport.close();
Source Code:
The functionality of this servlet is to get user input in its HTTP Servlet request and based on the values of the destination email address, the mail will be triggered from the application. However the sender address is the address that is maintained in the connectivity destination
package com.sap.cloud.sample.mail;
import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Servlet implementing a mail example which shows how to use the connectivity service APIs to send e-mail.
* The example provides a simple UI to compose an e-mail message and send it. The post method uses
* the connectivity service and the javax.mail API to send the e-mail.
*/
public class MailServlet extends HttpServlet {
@Resource(name = "mail/Session")
private Session mailSession;
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LoggerFactory.getLogger(MailServlet.class);
/** {@inheritDoc} */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Show input form to user
response.setHeader("Content-Type", "text/html");
PrintWriter writer = response.getWriter();
writer.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
+ "\"http://www.w3.org/TR/html4/loose.dtd\">");
writer.write("<html><head><title>Mail Test</title></head><body>");
writer.write("<form action='' method='post'>");
writer.write("<table style='width: 100%'>");
writer.write("<tr>");
writer.write("<td width='100px'><label>From:</label></td>");
writer.write("<td><input type='text' size='50' value='' name='fromaddress'></td>");
writer.write("</tr>");
writer.write("<tr>");
writer.write("<td><label>To:</label></td>");
writer.write("<td><input type='text' size='50' value='' name='toaddress'></td>");
writer.write("</tr>");
writer.write("<tr>");
writer.write("<td><label>Subject:</label></td>");
writer.write("<td><textarea rows='1' cols='100' name='subjecttext'>Subject</textarea></td>");
writer.write("</tr>");
writer.write("<tr>");
writer.write("<td><label>Mail:</label></td>");
writer.write("<td><textarea rows='7' cols='100' name='mailtext'>Mail Text</textarea></td>");
writer.write("</tr>");
writer.write("<tr>");
writer.write("<tr>");
writer.write("<td><input type='submit' value='Send Mail'></td>");
writer.write("</tr>");
writer.write("</table>");
writer.write("</form>");
writer.write("</body></html>");
}
/** {@inheritDoc} */
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
Transport transport = null;
try {
// Parse form parameters
String from = request.getParameter("fromaddress");
String to = request.getParameter("toaddress");
String subjectText = request.getParameter("subjecttext");
String mailText = request.getParameter("mailtext");
if (from.isEmpty() || to.isEmpty()) {
throw new RuntimeException("Form parameters From and To may not be empty!");
}
// Construct message from parameters
MimeMessage mimeMessage = new MimeMessage(mailSession);
InternetAddress[] fromAddress = InternetAddress.parse(from);
InternetAddress[] toAddresses = InternetAddress.parse(to);
mimeMessage.setFrom(fromAddress[0]);
mimeMessage.setRecipients(RecipientType.TO, toAddresses);
mimeMessage.setSubject(subjectText, "UTF-8");
MimeMultipart multiPart = new MimeMultipart("alternative");
MimeBodyPart part = new MimeBodyPart();
part.setText(mailText, "utf-8", "plain");
multiPart.addBodyPart(part);
mimeMessage.setContent(multiPart);
// Send mail
transport = mailSession.getTransport();
transport.connect();
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
// Confirm mail sending
response.getWriter().println(
"E-mail was sent (in local scenario stored in '<local-server>/work/mailservice'"
+ " - in cloud scenario using configured mail session).");
} catch (Exception e) {
LOGGER.error("Mail operation failed", e);
throw new ServletException(e);
}
finally {
// Close transport layer
if (transport != null) {
try {
transport.close();
} catch (MessagingException e) {
throw new ServletException(e);
}
}
}
}
}
Mail Destinations
A mail destination is used to specify the mail server settings for sending or fetching e-mail, such as the e-mail provider, e-mail account, and protocol configuration. The name of the mail destination must match the name used for the mail session resource. We can configure a mail destination directly in a destination editor or in a mail destination properties file. The mail destination then needs to be made available in the cloud. If a mail destination is updated, an application restart is required so that the new configuration becomes effective. The SMTP and SMTPS configurations in the destinations are shown below. This is shown for gmail domain server. In case of any other domain, we need to provide the SMTP host and port number for that particular domain.
SMTP:
SMTPS:
Testing the application:
Once the application is deployed to HCP, it can be accessed using the application URL which opens a simple HTML form for the user to fill up the relevant details.
Example: hcpdemotest@gmail.com is configured as the sender email id in this application.The credentials have been provided in the destination itself. However, the receiver email id is based upon user's choice. Here sourav.mukherjee@sap.com is used as recipient id.
Email received in inbox:
Common Troubleshooting Techniques:
In case of SMTP configuration for Gmail, the servlet may throw Authentication failed exception because of the following reasons:
Error Message: javax.mail.AuthenticationFailedException issue
Case 1: For Security Problem:
URL: https://www.google.com/settings/security/lesssecureapps
Enable access to less secure application from other devices or servers:
Case 2: Additional security feature for Gmail
URL: https://accounts.google.com/DisplayUnlockCaptcha
By continuing to this, user can unlock the Captcha mechanism.
Note:
We can also achieve the same functionality using XSJS in XS based applications as written in How to send mail from a productive HANA XS application
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
35 | |
25 | |
14 | |
13 | |
7 | |
7 | |
6 | |
6 | |
5 | |
5 |