iSeries EGL

All things EGL for the iSeries / i5 / Power System

Archive for the ‘Sending eMail using Java Mail’ Category

Sending eMail Using Java

leave a comment »

Using Java Mail to Send eMail with or without Attachments

This post presents a single Java class that can be used without modification in any application supporting Java or calls to methods of a Java class such as EGL or RPG.

 

The External Type describing the Java methods

Shown below is the EGL External Type that is used to expose the methods of the Java class used to send email. The details of the methods are revealed by the Java class source code.

package com.mig.claimchecksapproval.externaltypes;

externalType SendMail type JavaObject{PackageName = "com.mig.claimchecksapproval.mail"}

    constructor();
    function setMailServerAddress( value string in );
    function setMailServerPort( value string in );
    function setMailSentFromAddress( value string in ); 
    function setMailSentToAddress( value string in );
    function setMailSentCcToAddress( value string in );    
    function setSubject( value string in );
    function setMessageText( value string in );
    function setMailAttachmentPath( value string in );
    function setMailAttachmentFileName(value string in );
    function sendEmail() returns(string[]);
                          
end

Fig.1 – The EGL External Type

To send email, the EGL developer needs only to call the ‘Setter’ functions to provide the values needed by the process. Once the values have been established, to send the email, call the function ‘sendEmail()’. Present is a detailed list of the functions showing how to use them and what to expect.

  • function setMailServerAddress( value string in )
    This is the Address of the eMail server i.e. 123.456.789.1
    This value is mandatory.

  • function setMailServerPort( value string in )
    Port of the eMail server i.e. 25
    This value is mandatory.

  • function setMailSentFromAddress( value string in )
    The address of the sender i.e. DoNotReply@yourcompany.com
    This value is mandatory.

  • function setMailSentToAddress( value string in )
    The destination address i.e. rmendez@yourcompany.com
    This value is mandatory.

  • function setMailSentCcToAddress( value string in )
    The list of addresses for the carbon-copy i.e. rmendez@yourcompany.com, rmcdonald@yourcompany.com
    This value is optional. One or more addresses can be supplied but must be separated with commas.

  • function setSubject( value string in )
    The subject of the email
    This value is mandatory.

  • function setMessageText( value string in )
    The Message text
    This value is optional.

  • function setMailAttachmentPath( value string in )
    The path of the directory containing the attachment file i.e.

    During development:
      C:/Desk/AppDevEGL/ClaimChecksApproval/ClaimChecksApprovalProject/WebContent/content/
      		or
    During Testing:
      tomcat\TomcatTEST\webapps\ClaimChecksApproval\content\
      		or
    For production:
      tomcat\TomcatPROD\webapps\ClaimChecksApproval\content\ 
    

    This property is optional however, if the setMailAttachmentFileName is provided this is
    mandatory.

  • function setMailAttachmentFileName(value string in )
    The file name of the attachment file i.e.
    20121010151427ApprovedClaimChecks.pdf
    

    This property is optional however, if the MailAttachmentPath is provided this is
    mandatory.

  • function sendEmail() returns(string[])
    Once all of the required properties have been established, call this method to send the email.
    The method returns a list of messages related to the process indicating success or failure and
    are suitable for logging which is highly recommended.

 

The Java Class

Below is the Java class. The details behind the functions presented in the EGL External Type (Fig 1) above are revealed.
 

package com.app.utilities.general;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
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 com.app.utilities.general.StringRoutines;


/**
 * 
 * This class provides the ability to create an email with an attachment which can be a
 * file of any type.   For attachments all that is required is the path and file name.
 * 
 * @author benfoster
 *
 */
public class SendMail {

	private String emailServerAddress = null;
	private String emailServerPort = null;
	
	private String emailSentFromAddress = null;
	private String emailSentToAddress = null;
	private String emailSentCcToAddress = null;	
	private String emailSubject = null;
	private String emailMessageText = null;
	private String emailMailAttachmentPath = null;
	private String emailMailAttachmentFileName = null;
	
	List listOfEvents = new ArrayList();
	
	
	/**
	 * Constructor
	 */
	public SendMail() {

	}

	
	/**
	 * This is the Address of the eMail server i.e. 192.168.128.1
	 * @param value
	 */
	public void setMailServerAddress(String value) {
		this.emailServerAddress = value;
	}
	
	/**
	 * Port of the eMail server i.e. 25
	 * @param value
	 */
	public void setMailServerPort(String value) {
		this.emailServerPort = value;
	}
	
	/**
	 * The address of the sender i.e. DoNotReply@manhattanlife.com
	 * @param value
	 */	
	public void setMailSentFromAddress(String value) {
		this.emailSentFromAddress = value;
	}
	
	/**
	 *  The destination address i.e. bfoster@manhattanlife.com
	 * @param value
	 */	
	public void setMailSentToAddress(String value) {
		this.emailSentToAddress = value;
	}
	
	/**
	 *  The list of addresses for the carbon-copy i.e. bfoster@manhattanlife.com, klubin@manhattanlife.com
	 * @param value
	 */	
	public void setMailSentCcToAddress(String value) {
		this.emailSentCcToAddress = value;
	}	
	
	/**
	 * The subject of the email
	 * @param value
	 */	
	public void setSubject(String value) {
		this.emailSubject = value;
	}

	/**
	 * The Message text  
	 * @param value
	 */	
	public void setMessageText(String value) {
		this.emailMessageText = value;
	}

	/**
	 * The path of the directory containing the attachment file i.e.
	 * C:/Desk/AppDevEGL/ClaimChecksApproval/ClaimChecksApprovalProject/WebContent/content/
	 * 		or
	 * tomcat\Tomcat6032T\webapps\ClaimChecksApproval\content\
	 * 
	 * This property is optional however, if  the setMailAttachmentFileName is provided this is
	 * mandatory.
	 *  
	 * @param value
	 */
	public void setMailAttachmentPath (String value) {
		this.emailMailAttachmentPath = value;
	}

	
	/**
	 *  The file name of the attachment file i.e. 20121010151427ApprovedClaimChecks.pdf
	 *  
	 * This property is optional however, if  the MailAttachmentPath is provided this is
	 * mandatory.
	 * 
	 * @param value
	 */
	public void setMailAttachmentFileName(String value) {
		this.emailMailAttachmentFileName = value;
	}
	
	
	/**
	 * Once all of the required properties have been established, call this method to send the email.
	 * 
	 * @return List A list of messages related to the process indicating success or failure.
	 */
	public List sendEmail() {

		if ( emailServerAddress == null || emailServerPort == null || emailSentFromAddress == null || 
		 emailSentToAddress == null || emailSentCcToAddress == null ||  emailSubject == null  
		) {
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): One or more required parameters are missing. Process aborted.");	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Failed" + emailMailAttachmentFileName);				
			return listOfEvents;
		}
		
		
		//String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
		
		Properties props = new Properties();
		props.put("mail.smtp.host", emailServerAddress);
		props.put("mail.smtp.port", emailServerPort);
        	//props.put("mail.transport.protocol.", "smtp");
        	//props.put("mail.smtp.auth", "false");
        	//props.put("mail.smtp.", "true");
        	props.put("mail.from", emailSentFromAddress);
        	props.put("mail.to", emailSentToAddress);
        	props.put("mail.cc", emailSentCcToAddress);
        	props.put("mail.smtp.socketFactory.fallback", "false");
        	//props.put("mail.smtp.socketFactory.class", SSL_FACTORY);		
		
        	Session mailSession = Session.getInstance(props, null);
        	mailSession.setDebug(true);
        
        	//Initialize a StringRoutines object.
        	StringRoutines sr = new StringRoutines();
        
        
		//Test for supplied emailMailAttachmentPath and emailMailAttachmentFileName
		if( !sr.isBlank(this.emailMailAttachmentPath) && sr.isBlank(this.emailMailAttachmentFileName) ){
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): emailMailAttachmentPath supplied but emailMailAttachmentFileName is blank.");	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): emailMailAttachmentPath value is " + emailMailAttachmentPath);	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): emailMailAttachmentFileName value is " + emailMailAttachmentFileName);	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Failed" + emailMailAttachmentFileName);	
			return listOfEvents;        	
		}
		if( sr.isBlank(this.emailMailAttachmentPath) && !sr.isBlank(this.emailMailAttachmentFileName) ){
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): emailMailAttachmentPath is blank but emailMailAttachmentFileName is supplied.");	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): emailMailAttachmentPath value is " + emailMailAttachmentPath);	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): emailMailAttachmentFileName value is " + emailMailAttachmentFileName);	
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Failed" + emailMailAttachmentFileName);	
			return listOfEvents;        	
		}        
        
        
		String pathAndFile = this.emailMailAttachmentPath + emailMailAttachmentFileName;

		try {
			// create a message
			MimeMessage msg = new MimeMessage(mailSession);
			msg.setFrom(new InternetAddress(emailSentFromAddress));

			InternetAddress[] address = {new InternetAddress(emailSentToAddress)};
			msg.setRecipients(Message.RecipientType.TO, address);

			//This uses the StringRoutines class of the AppUtilities project in which this class
			//also resides.  It accepts a token-separated list of string values and separates them
			//into a vector i.e. an array list that can be used in a loop to operate upon the 
			//individual entries.  In this case we are using the values as entries in the Cc part
			//of an email.
			Vector vectorOfAddresses = sr.separateWordsUsingToken(emailSentCcToAddress, ",");
			for(int idx = 0; idx < vectorOfAddresses.size(); idx++) {
			  String ccEmailAddress = (String)vectorOfAddresses.get(idx);
			  msg.addRecipient( Message.RecipientType.CC, new InternetAddress(ccEmailAddress) );
			}

			msg.setSubject(emailSubject);

			// create and fill the first message part
			MimeBodyPart mbp1 = new MimeBodyPart();
			mbp1.setText(emailMessageText);

			//If pathAndFile is not blank add the file specified as an attachment.
			if( !sr.isBlank(pathAndFile) ) {
			      // create the second message part
			      MimeBodyPart mbp2 = new MimeBodyPart();

			      // attach the file to the message
			      FileDataSource fds = new FileDataSource(pathAndFile);
			      mbp2.setDataHandler(new DataHandler(fds));
			      mbp2.setFileName(fds.getName());

			      // create the Multipart and add its parts to it
			      Multipart mp = new MimeMultipart();
			      mp.addBodyPart(mbp1);
			      mp.addBodyPart(mbp2);

			      // add the Multipart to the message
			      msg.setContent(mp);
			}

			// set the Date: header
			msg.setSentDate(new Date());

			// send the message
			Transport.send(msg);

			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Email sent.");
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Success" + emailMailAttachmentFileName);			      
		} catch (MessagingException mex) {
			mex.printStackTrace();
			Exception ex = null;
			if ((ex = mex.getNextException()) != null) {
			  ex.printStackTrace();
			}
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Email failed with exception : " + mex);
			listOfEvents.add("SendMail.sendApprovalProcessEmail(): Failed" + emailMailAttachmentFileName);	
		}
		

		return(listOfEvents);
		
	}
}



Fig.2 – The Java Class that does all the work.

 

The EGL Code that goes into the Service program.

Shown below is the segment of code that is added to the Service part. In addition to the External Type shown in Fig 1., it is all the code required by the EGL developer to create and send an email.

All of the heavy work is being accomplished by the Java class, SendMail shown in Fig. 2.

            //************************************************************
            // Email the PDF document created in a previous step to the
            // recipients designated in the applicationConfig.xml file.
            //************************************************************           
            sendMail Sendmail = new SendMail();
            sendMail.setMailServerAddress(globalDataRecord.emailServerAddress);
            sendMail.setMailServerPort(globalDataRecord.emailServerPort);
            sendMail.setMailSentFromAddress(globalDataRecord.emailFromAddress);
            sendMail.setMailSentToAddress(globalDataRecord.emailTo);
            sendMail.setMailSentCcToAddress(globalDataRecord.emailCcTo);
            sendMail.setSubject("Claim Checks Print Request");
            sendMail.setMessageText(" "); 
            sendMail.setMailAttachmentPath(globalDataRecord.pdfFilesLocation);
            sendMail.setMailAttachmentFileName(pdfFileName);
            events String[] = sendMail.sendEmail();

Fig.3 – The EGL code used to eMail from an EGL Service

 

Conclusion

As can be seen, sending eMail from EGL is easily accomplished by the use of a simple Java class. Packaged into a .jar file and included in any EGL project it can be reused across many projects.

 
 

Written by iseriesadmin

October 11, 2012 at 9:23 am