Java Mail API - Yash-777/LearnJava GitHub Wiki

JavaMail

The JavaMail API provides a platform-independent and protocol-independent framework for sending and receiving mails. The JavaMail API is available as an optional package for use with the Java SE platform and is also included in the Java EE platform. By using JavaMail API we can send, receive, delete, manage the emails.

The JavaMail in Detail PDF links

Usege Scenario:

Sending an email from with a Java application has many practical uses. A web application may allow visitors to create an account. Part of the account creation process could include sending an email with a unique activation code to verify that a valid email address was given at signup, forgot password (sending password to the users email id). Online shopping applications typically notify buyers of order or tracking status via email.

Following are some of the protocols supported in JavaMail API:

SMTP, POP, IMAP, MIME, NNTP

  • SMTP « Acronym for Simple Mail Transfer Protocol. It provides a mechanism to deliver/send electronic mail(Email). An authentication is required in case of sending and receiving the emails through SMTP server which was provided by host server like host name, port number, and security settings. We can use Apache James server, Postcast server, cmail server etc. as an SMTP server. if we purchase the host space, an SMTP server is bydefault provided by the host provider. For example, my smtp server is mail.javatpoint.com. If we use the SMTP server provided by the host provider, authentication is required for sending and receiving emails.

  • POP « Acronym for Post Office Protocol, also known as POP3 - Post Office Protocol version 3. It provides a mechanism to receive/get their emails. It defines support for a single mailbox for each user. RFC 1939 defines this protocol.

  • IMAP « Acronym for Internet Message Access Protocol. It is an advanced protocol for receiving messages. It provides support for multiple mailbox for each user and also provides the facility to share a single mailbox among multiple users. It is defined in RFC 2060.

  • MIME « Acronym for Multipurpose Internet Mail Extensions. It is not a mail transfer protocol. Instead, it defines the content of what is transferred: the format of the messages, attachments, and so on. There are many different documents that take effect here: RFC 822, RFC 2045, RFC 2046, and RFC 2047.

  • NNTP « There are many protocols that are provided by third-party providers. Some of them are Network News Transfer Protocol (NNTP), Secure Multipurpose Internet Mail Extensions (S/MIME) etc.


JavaMail Layered Architecture components:

  • The Abstract Layer declares classes, interfaces and abstract methods intended to support mail handling functions that all mail systems support. API elements comprising the Abstract Layer are intended to be sub-classed and extended as necessary in order to support standard data types, and to interface with message access and message transport protocols as necessary.
  • The internet implementation layer implements part of the abstract layer using internet standards - RFC822 and MIME.
  • Java-mail uses the JavaBeans Activation Framework (JAF) in order to encapsulate message data, and to handle commands intended to interact with that data. Interaction with message data should take place via JAF-aware JavaBeans, which are not provided by the JavaMail API.

Client,JavaMailAPI,ServiceProvider

JavaMail clients use the JavaMail API and Service Providers implement the JavaMail API. The layered design architecture allows clients to use the same JavaMail API calls to send, receive and store a variety of messages using different data-types from different message stores and using different message transport protocols.


The JavaMail Framework

The JavaMail API is intended to perform the following functions, which comprise the standard mail handling process for a typical client application:

  • Create a mail message consisting of a collection of header attributes and a block of data of some known data type as specified in the Content-Type header field. JavaMail uses the Part interface and the Message class to define a mail message. It uses the JAF-defined DataHandler object to contain data placed in the message.
  • Create a Session object, which authenticates the user, and controls access to the message store and transport.
  • Send the message to its recipient list.
  • Retrieve a message from a message store.
  • Execute a high-level command on a retrieved message. High-level commands like view and print are intended to be implemented via JAF-Aware JavaBeans.

Mail Handling Process

Note – The JavaMail framework does not define mechanisms that support message delivery, security, disconnected peration, directory services or filter functionality.


The Structure of a Message

The Message class models an electronic mail message. It is an abstract class that implements the Part interface.

The Message class defines a set of attributes and content for an electronic mail message. The attributes, which are name-value pairs, specify addressing information and define the structure of the message’s content (its content type). Messages can contain a single content object or, indirectly, multiple content objects. In either case, the content is held by a DataHandler object.

Simple Messages « A simple message has a single content object, which is wrapped by a DataHandler object.

Multipart Messages « In this case the DataHandler object contains a Multipart object, instead of merely a a single block of content data. A Multipart object is a container of BodyPart objects. The structure of a BodyPart object is similar to the structure of a Message object, because they both implement the Part interface.

Each BodyPart object contains attributes and content, but the attributes of a Bodypart object are limited to those defined by the Part interface. An important attribute is the content-type of this part of the message content. The content of a BodyPart object is a DataHandler that contains either data or another Multipart object.

Message Structure

Prerequisites to Send EMail:

To send an e-mail using your Java Application is simple enough but to start with you should have JavaMail API(mail-1.4.7.jar) and Java Activation Framework (JAF - activation-1.1.1.jar) installed on your machine.

Note: If you are using JDK 1.6.0_10 or later then no need to worry about JAF, Which is included and available on javax.activation package. We suggest you use version 1.1.1 of JAF as if you use JDK version lesthan JDK 1.6.0_10.

SMPT server « Eighter you Install and use any SMTP server such as Postfix server (for Ubuntu), Apache James server (Java Apache Mail Enterprise Server)etc. (or) Use SMPT server provided by Gmail, which offers to use their public SMTP server for free of charge. Get SMTP Server details form here...

Example:

public enum MailDomain {
	USER_NAME("*****@gmail.com"), PASSWORD("*****");
	
	private String value;
	MailDomain(final String value) {	this.value = value;	}
	public String getValue() {	return value;	}
}

public class MailSenderSMTPGmail_Client {
	
	private static String TO_ADDRESS = "*****@gmail.com";
	
	public static void main(String[] args) {
		
		String subject = "Testing Subject";
		String electronic_Message = "MIME message Body - Test Mail using JavaMailAPI";
		String contentType = "Inline File"; // plain | HTML | Attached File | Inline File
		
		if( sendMail(subject, contentType, electronic_Message, TO_ADDRESS) ) {
			System.out.println("Sent message successfully.");
		} else {
			System.out.println("message failed.");
		}
	}
	
	public static boolean sendMail(String subject, String contentType, String body, String recipients) {
		
		String mailhost = "smtp.gmail.com", mailport = "465";
		// mail.domain.com [587]
		Session mailSession = getSessionObject(mailhost, mailport, true);
		try {
			// Create a default MimeMessage object.
			Message message = new MimeMessage( mailSession );
			message.setFrom( new InternetAddress( MailDomain.USER_NAME.getValue() ) );
			
			message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(TO_ADDRESS));
			
			message.setSubject( subject );
			
			// Multipart Message - [Attached File, In-line Images]
			if( contentType.equalsIgnoreCase("Attached File") ) {
				Multipart multipart = new MimeMultipart();
				
				// Create a mime body and Set Text
				BodyPart messageBodyPart = new MimeBodyPart();
				messageBodyPart.setText( body );
				multipart.addBodyPart( messageBodyPart );

				String filename = "D:\\Test.js";
				// Part two is attachment
				BodyPart  fileBodyPart = new MimeBodyPart();
				DataSource source = new javax.activation.FileDataSource( filename );
				fileBodyPart.setDataHandler( new DataHandler( source ) );
				fileBodyPart.setFileName( filename );
				multipart.addBodyPart( fileBodyPart );

				//http://www.oracle.com/technetwork/java/javamail/faq/index.html#overridefiletype
				// Send the complete message parts
				message.setContent( multipart, Part.ATTACHMENT ); // "multipart/*"
			} else if( contentType.equalsIgnoreCase("Inline File") ) {
				Multipart multipart = new MimeMultipart();
				
				// Create a mime body and Set Text
				BodyPart messageBodyPart = new MimeBodyPart();
				String htmlText = "<H1>Hello</H1><img src=\"cid:image\">";// Get from Header
				messageBodyPart.setContent(htmlText, "text/html");
				multipart.addBodyPart( messageBodyPart );

				String filename = "H:\\MailMesageBody.png";
				BodyPart  fileBodyPart = new MimeBodyPart();
				DataSource source = new javax.activation.FileDataSource( filename );
				fileBodyPart.setDataHandler( new DataHandler( source ) );
				String header_name = "Content-ID", header_value = "<image>";
				fileBodyPart.setHeader(header_name, header_value);
				multipart.addBodyPart( fileBodyPart );

				// Send the complete message parts
				message.setContent( multipart, Part.INLINE );
			} else if ( contentType.equalsIgnoreCase("HTML") ) {
				String htmlData = "<h1>This is actual message embedded in HTML tags</h1>";
				message.setContent( htmlData, "text/html");
			} else { //Simple Message - [Plain Text | HTML Content]
				String header_name = "Content-ID", header_value = "<b>";
				message.addHeader( header_name, header_value );
				message.setContent( body, "text/plain" ); 
				//(OR) message.setText( body );
			}
			
			// Send message
			Transport transport = mailSession.getTransport("smtps");
			transport.connect(mailhost, MailDomain.USER_NAME.getValue(), MailDomain.PASSWORD.getValue());
			message.saveChanges();
			transport.sendMessage(message, message.getAllRecipients());
			transport.close();
			System.out.println("Sent message successfully.");
			return true;
		} catch (AddressException ex) {
			System.out.println(ex);
		} catch (MessagingException ex) {
			System.out.println(ex);
		} catch(Exception ex) {
			System.out.println(ex);
		}
		return false;
	}
	
	public static Session getSessionObject(String mailhost, String mailport, boolean authProps) {
		System.out.println("==- Outgoing Mail (SMTP) Server details like SMTP properties and Authenticate -==");
		Properties props = new Properties();
		props.put("mail.transport.protocol", "smtp");
		props.put("mail.smtp.host", mailhost);
		props.put("mail.smtp.port", mailport);
		
		props.put("mail.smtp.auth", "true");
		if( mailport.equals("587") ) {
			props.put("mail.smtp.starttls.enable", "true");
		} else {
			props.put("mail.smtps.ssl.enable", "true");
		}
		props.put("mail.smtp.socketFactory", "javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.fallback", "false");
		props.put("mail.smtp.debug", "true");
		props.put("mail.smtp.quitwait", "false");
		
		//create Authenticator object to pass in Session.getInstance argument
		Authenticator authenticator = new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
			PasswordAuthentication passwordAuthentication = new PasswordAuthentication(
					MailDomain.USER_NAME.getValue(), MailDomain.USER_NAME.getValue());
			return passwordAuthentication;
			}
		};
		
		// com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required.
		Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
		
		// Get the Session object by Authenticating Password.
		if ( authProps ){
			props.put("mail.smtp.user", MailDomain.USER_NAME.getValue());
			props.put("mail.smtp.password", MailDomain.PASSWORD.getValue());
			System.out.println("Session DefaultInstance");
			return Session.getDefaultInstance(props);
			//return Session.getInstance(props);
		}
		System.out.println("Session Instance with Authentication");
		//return Session.getDefaultInstance(props, authenticator);
		return Session.getInstance(props, authenticator);
	}
}
⚠️ **GitHub.com Fallback** ⚠️