Friday, May 23, 2014

Sending E-Mail using SSL (Java) : Gmail Demonstration [Note]

So I found out this really useful article here at SOURCE


Sending emails is one of the common tasks in real life applications and that’s why Java provides robustJavaMail API that we can use to send emails using SMTP server. JavaMail API supports both TLS and SSL authentication for sending emails.
Today we will learn how to use JavaMail API to send emails using SMTP server with no authentication, TLS and SSL authentication and how to send attachments and attach and use images in the email body. For TLS and SSL authentication, I am using GMail SMTP server because it supports both of them.
JavaMail API is not part of standard JDK, so you will have to download it from it’s official website i.e JavaMail Home Page. Download the latest version of the JavaMail reference implementation and include it in your project build path. The jar file name will be javax.mail.jar.
Java Program to send email contains following steps:
  1. Creating javax.mail.Session object
  2. Creating javax.mail.internet.MimeMessage object, we have to set different properties in this object such as recipient email address, Email Subject, Reply-To email, email body, attachments etc.
  3. Using javax.mail.Transport to send the email message.
The logic to create session differs based on the type of SMTP server, for example if SMTP server doesn’t require any authentication we can create the Session object with some simple properties whereas if it requires TLS or SSL authentication, then logic to create will differ.
So I will create a utility class with some utility methods to send emails and then I will use this utility method with different SMTP servers.
Here's the code:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
import javax.activation.*;
import javax.mail.*;
import javax.mail.*;
import javax.mail.internet.*;

class EmailUtil {

    /**
     * Utility method to send simple HTML email
     *
     * @param session
     * @param toEmail
     * @param subject
     * @param body
     */
    public static void sendEmail(Session session, String toEmail, String subject, String body) {
        try {
            MimeMessage msg = new MimeMessage(session);
            //set message headers
            msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
            msg.addHeader("format", "flowed");
            msg.addHeader("Content-Transfer-Encoding", "8bit");

            msg.setFrom(new InternetAddress("abc@xyz.com", "NoReply-JD"));

            msg.setReplyTo(InternetAddress.parse("abc@xyz.com", false));

            msg.setSubject(subject, "UTF-8");

            msg.setText(body, "UTF-8");

            msg.setSentDate(new Date());

            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
            System.out.println("\nSending Mail Now...");
            Transport.send(msg);

            System.out.println("\nEMail Sent Successfully!");
        } catch (Exception e) {
            e.printStackTrace();

        }

    }
}

public class SSLEmail {

    /**
     * Outgoing Mail (SMTP) Server requires TLS or SSL: smtp.gmail.com (use
     * authentication) Use Authentication: Yes Port for SSL: 465
     */
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("Enter your GMail id: ");
        final String fromEmail = br.readLine(); //requires valid gmail id
        System.out.println("Password: ");
        final String password = br.readLine(); // correct password for gmail id
        System.out.println("Send To: ");
        final String toEmail = br.readLine(); // can be any email id 

        System.out.println("\nSSL Email Start");
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
        props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
        props.put("mail.smtp.socketFactory.class",
                "javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
        props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
        props.put("mail.smtp.port", "465"); //SMTP Port
        props.put("mail.smtp.connectiontimeout", "5000");
        props.put("mail.smtp.timeout", "5000");
        Authenticator auth = new Authenticator() {
            //override the getPasswordAuthentication method
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, password);
            }
        };

        Session session = Session.getDefaultInstance(props, auth);
        System.out.println("Session created");
        System.out.println("Subject: ");
        String subject = br.readLine();
        System.out.println("Body: [newline \"X\" ends the input]");
        String temp = "";
        String body="";
        while(!(temp=br.readLine()).equals("X")){
            body+=temp;
        }
        EmailUtil.sendEmail(session, toEmail, subject, body);
    }
}

Make sure to turn windows firewall off if you encouter problems like -
1. Program hanging on Transport.send(msg)  //happened with me

If you've just started, it will be very helpful to know what MIME is:

Multipurpose Internet Mail Extensions (MIME) is an Internet standard that extends the format of email to support:
  • Text in character sets other than ASCII
  • Non-text attachments
  • Message bodies with multiple parts
  • Header information in non-ASCII character sets
Although MIME was designed mainly for SMTP protocol, its use today has grown beyond describing the content of email and now often includes descriptions of content type in general, including for the web (see Internet media type) and as a storage for rich content in some commercial products (e.g., IBM Lotus Domino and IBM Lotus Quickr).
Virtually all human-written Internet email and a fairly large proportion of automated email is transmitted via SMTP in MIME format. Internet email is so closely associated with the SMTP and MIME standards that it is sometimes called SMTP/MIME email.[1]
The content types defined by MIME standards are also of importance outside of email, such as in communication protocols like HTTPfor the World Wide Web. HTTP requires that data be transmitted in the context of email-like messages, although the data most often is not actually email.

Introduction

The basic Internet email transmission protocol, SMTP, supports only 7-bit ASCII characters (see also 8BITMIME). This effectively limits Internet email to messages which, when transmitted, include only the characters sufficient for writing a small number of languages, primarily English. Other languages based on the Latin alphabet typically include diacriticsand are not supported in 7-bit ASCII, meaning text in these languages cannot be correctly represented in basic email.
MIME defines mechanisms for sending other kinds of information in email. These include text in languages other than English using character encodings other than ASCII, and 8-bit binary content such as files containing imagessoundsmovies, and computer programs. Parts of MIME are also reused in communication protocols such as HTTP, which requires that data be transmitted in the context of email-like messages even though the data might not (and usually does not) actually have anything to do with email, and the message body can actually be binary. Mapping messages into and out of MIME format is typically done automatically by an email client or by mail servers when sending or receiving Internet (SMTP/MIME) email.
The basic format of Internet email is defined in RFC5523, which is an updated version of RFC2822 and RFC822. These standards specify the familiar formats for text email headers and body and rules pertaining to commonly used header fields such as "To:", "Subject:", "From:", and "Date:". MIME defines a collection of email headers for specifying additional attributes of a message including content type, and defines a set of transfer encodings which can be used to represent 8-bit binary data using characters from the 7-bit ASCII character set. MIME also specifies rules for encoding non-ASCII characters in email message headers, such as "Subject:", allowing these header fields to contain non-English characters.
MIME is extensible. Its definition includes a method to register new content types and other MIME attribute values.
The goals of the MIME definition included requiring no changes to existing email servers and allowing plain text email to function in both directions with existing clients. These goals were achieved by using additional RFC 822 style headers for all MIME message attributes and by making the MIME headers optional with default values ensuring a non-MIME message is interpreted correctly by a MIME-capable client. A simple MIME text message is therefore likely to be interpreted correctly by a non-MIME client even if it has email headers which the non-MIME client will not know how to interpret. Similarly, if the quoted printable transfer encoding (see below) is used, the ASCII part of the message will be intelligible to users with non-MIME clients.

MIME headers

MIME-Version

The presence of this header indicates the message is MIME-formatted. The value is typically "1.0" so this header appears as
MIME-Version: 1.0
According to MIME co-creator Nathaniel Borenstein, the intention was to allow MIME to change, to advance to version 2.0 and so forth, but this decision led to the opposite outcome, making it nearly impossible to create a new version of the standard.
"We did not adequately specify how to handle a future MIME version," Borenstein said. "So if you write something that knows 1.0, what should you do if you encounter 2.0 or 1.1? I sort of thought it was obvious but it turned out everyone implemented that in different ways. And the result is that it would be just about impossible for the Internet to ever define a 2.0 or a 1.1."[2]

Content-Type

This header indicates the Internet media type of the message content, consisting of a type and subtype, for example
Content-Type: text/plain
Through the use of the multipart type, MIME allows mail messages to have parts arranged in a tree structure where the leaf nodes are any non-multipart content type and the non-leaf nodes are any of a variety of multipart types. This mechanism supports:
  • simple text messages using text/plain (the default value for "Content-Type: ")
  • text plus attachments (multipart/mixed with a text/plain part and other non-text parts). A MIME message including an attached file generally indicates the file's original name with the "Content-disposition:" header, so the type of file is indicated both by the MIME content-type and the (usually OS-specific) filename extension
  • reply with original attached (multipart/mixed with a text/plain part and the original message as a message/rfc822 part)
  • alternative content, such as a message sent in both plain text and another format such as HTML (multipart/alternative with the same content in text/plain and text/html forms)
  • image, audio, video and application (for example, image/jpegaudio/mp3video/mp4, and application/msword and so on)
  • many other message constructs

Content-Disposition

The original MIME specifications only described the structure of mail messages. They did not address the issue of presentation styles. The content-disposition header field was added in RFC2183 to specify the presentation style. A MIME part can have:
  • an inline content-disposition, which means that it should be automatically displayed when the message is displayed, or
  • an attachment content-disposition, in which case it is not displayed automatically and requires some form of action from the user to open it.
In addition to the presentation style, the content-disposition header also provides fields for specifying the name of the file, the creation date and modification date, which can be used by the reader's mail user agent to store the attachment.
The following example is taken from RFC2193, where the header is defined
Content-Disposition: attachment; filename=genome.jpeg;
  modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
The filename may be encoded as defined by RFC2231.
As of 2010, a good majority of mail user agents do not follow this prescription fully. The widely used Mozilla Thunderbird mail client makes its own decisions about which MIME parts should be automatically displayed, ignoring the content-disposition headers in the messages. Thunderbird prior to version 3 also sends out newly composed messages with inlinecontent-disposition for all MIME parts. Most users are unaware of how to set the content-disposition to attachment.[3] Many mail user agents also send messages with the file name in the name parameter of the content-type header instead of the filename parameter of the content-disposition header. This practice is discouraged – the file name should be specified either through just the filename parameter, or through both the filename and the name parameters.[4]
In HTTP, the Content-Disposition: attachment response header is usually used to hint to the client to present the response body as a downloadable file. Typically, when receiving such a response, a Web browser will prompt the user to save its content as a file instead of displaying it as a page in a browser window, with the filename parameter suggesting the default file name (this is useful for dynamically generated content, where deriving the filename from the URL may be meaningless or confusing to the user).

Content-Transfer-Encoding

In June 1992, MIME defined a set of methods for representing binary data in formats other than ASCII text format. The content-transfer-encoding: MIME header has 2-sided significance:
  • It indicates whether or not a binary-to-text encoding scheme has been used on top of the original encoding as specified within the Content-Type header:
  1. If such a binary-to-text encoding method has been used, it states which one.
  2. If not, it provides a descriptive label for the format of content, with respect to the presence of 8 bit or binary content.
The RFC and the IANA's list of transfer encodings define the values shown below, which are not case sensitive. Note that '7bit', '8bit', and 'binary' mean that no binary-to-text encoding on top of the original encoding was used. In these cases, the header is actually redundant for the email client to decode the message body, but it may still be useful as an indicator of what type of object is being sent. Values 'quoted-printable' and 'base64' tell the email client that a binary-to-text encoding scheme was used and that appropriate initial decoding is necessary before the message can be read with its original encoding (e.g. UTF-8).
  • Suitable for use with normal SMTP:
    • 7bit – up to 998 octets per line of the code range 1..127 with CR and LF (codes 13 and 10 respectively) only allowed to appear as part of a CRLF line ending. This is the default value.
    • quoted-printable – used to encode arbitrary octet sequences into a form that satisfies the rules of 7bit. Designed to be efficient and mostly human readable when used for text data consisting primarily of US-ASCII characters but also containing a small proportion of bytes with values outside that range.
    • base64 – used to encode arbitrary octet sequences into a form that satisfies the rules of 7bit. Designed to be efficient for non-text 8 bit and binary data. Sometimes used for text data that frequently uses non-US-ASCII characters.
  • Suitable for use with SMTP servers that support the 8BITMIME SMTP extension:
    • 8bit – up to 998 octets per line with CR and LF (codes 13 and 10 respectively) only allowed to appear as part of a CRLF line ending.
  • Suitable only for use with SMTP servers that support the BINARYMIME SMTP extension :
    • binary – any sequence of octets.
There is no encoding defined which is explicitly designed for sending arbitrary binary data through SMTP transports with the 8BITMIME extension. Thus base64 or quoted-printable (with their associated inefficiency) must sometimes still be used. This restriction does not apply to other uses of MIME such as Web Services with MIME attachments or MTOM.

More on MIME : MIME-Wikipeida-link
Some more useful links you might wanna check:
1. Tutorial [Oracle]
2. developers.google.com/...

No comments:

Post a Comment