The email messages, we have developed so far, have only text content. In this section, we shall discuss creating messages having text and/or non-text content.
1. MIME
Note that, SMTP was originally designed to transfer only plain (ASCII) text. The maximum number of characters and lines were also limited. To overcome these limitations, a standard was defined by Internet Engineering Task Force (IETF) in RFC 1521 and 1522 called Multipurpose Internet Mail Extension (MIME). MIME is a standard intended for enhancing the capabilities of SMTP. It provides a simple and standard way to represent and encode a wide variety of media types for transmission via SMTP.
MIME especially supports the following:
- Both ASCII and non-ASCII character sets
- Messages having unlimited length
- Multi-font messages
- Multi-media: Image, Audio, and Video messages
- Multi-objects in a single message
- Even raw binary files
Moreover, MIME specification was built to be completely backward compatible and flexible and open to extensions. It enables us describing and organizing new content type by defining additional fields in the email header.
The javax.mail.internet.MimeMessage class, which is a subclass of abstract javax.mail.Message class, implements MIME messages. A MIME message has basically two parts: header and body.
The header section contains attributes that specify address(es) and other values necessary to send, route, receive, decode and store the message. Attributes also specify the structure and type of data contained in the message body.
The content of Message may consist of a single part or multiple parts. A single part Message is one which has only one section of data, whereas multi-part Message has a body having multiple sections.
2. Single-part Message
In this case, the content of a Message is represented by a javax.activation.DataHandler object, which carries the content and provides useful methods to handle the content. A DataHandier object knows how to deal with the content. To add content to a Message, the following steps are followed:
- Create some content
- Instantiate a DataHandier object
- Place content into that DataHandier object
- Place that DataHandier object into a Message object
- Define attributes for this DataHandier object in the Message header properly
The JavaMail API provides two methods setDataHandier() and setContent () to set the message content:
void setDataHandler(DataHandler dh)
void setContent(Object obj, String type)
void setContent(Multipart mp)
The first two are used for messages having a single part and the last method is used for multi-part message and is described in the next section.
Using setDataHandler()
In this case, we use setDataHanider() method on Message to set a DataHandier that encapsulates data. The DataHandier class provides a consistent interface to data obtained in different formats and sources. A DataHandier object may be created using any of the following constructors:
DataHandler(DataSource ds)
DataHandler(Object obj, String mimeType)
DataHandler(URL url)
The constructors accept data as either a DataSource, which is a stream connected to the data or a Java Object or a url. For example, the following example creates a DataHandier object from a String:
//create a String
String content = “simple string”;
//create a DataHandier object with this String
DataHandier dh = new DataHandler(content, “text/plain”);
The second argument indicates that the content is plain text type. Similarly, the following code creates a DataHandier object from file data:
String filename = “SendEmailTest.java”;
DataSource ds = new FileDataSource(filename);
DataHandier dh = new DataHandler(ds);
We can now insert the DataHandier object dh having content into the Message object msg as follows:
//insert content to the message
msg.setDataHandler(dh);
Note that the content set by the last setDataHanider() method persists overwriting existing (if any) content.
Using setContent()
In this case, we can set content to a Message using its setContent () method directly. The following example illustrates this:
//create a String
String content = “simple string”;
//insert content to the message directly
msg.setContent(content, “text/plain”);
3. Multi-part MIME message
In this case, message content is represented by a Multipart object. A Multipart object is a container that contains one or more Bodypart objects, each of which can in turn contain DataHandler objects. For example, if a message has a text content and an attachment, the message is said to have two body parts.
The javax.mail.internet.MimeMultipart class, which is a subclass of abstract javax.mail. Multipart class, represents a muti-part content. To create a message having multiple parts, the following steps are followed:
- Create a MimeMultipart object or create an object of a class that extends Multipart
- Create one or more MimeBodyPart object one for each part of the message content
- Populate these objects using setContent() or setDataHandler() method as described in the previous section
- Insert the MimeMultipart object into the message using setContent()
4. Composing a Mixed Message
In this section, we shall compose a message which has text content and an attachment (i.e. multiple parts). To create a message having multiple parts, we first create a MimeMuitipart object:
Multipart multipart = new MimeMultipart();
Since, there are two body parts (one text and another attachment) in our message, we create two MimeBodyPart objects as follows:
MimeBodyPart parti = new MimeBodyPart();
MimeBodyPart part2 = new MimeBodyPart();
The first part part1 holds a text message and the second part part2 holds an attachment. A piece of text is placed in the first part as follows:
part1.setContent(”This mail has an attachment.”, ”text/plain”);
Since, the content type is plain text, setText() may also be used:
part1.setText(”This mail has an attachment.”);
The setText() method sets the specified String to the parti with a MIME type of text/plain. Let us now attach a file EmailWithAttachment.java with the second part as follows:
String filename = ”EmailWithAttachment.java”;
DataSource source = new FileDataSource(filename);
DataHandler dh = new DataHandler(source);
part2.setDataHandler(dh);
part2.setFileName(filename);
Alternatively, to be concise, attachFile() method may be used:
String filename = ”EmailWithAttachment.java”;
part2.attachFile(filename);
The attachFile() uses the given file to provide the data for part2. The file name specified is used as the file name for this part and file data is used as the data for this part. The encoding is done appropriately based on file data. These two parts are then added to the MimeMultipart object as follows:
multipart.addBodyPart(partl);
multipart.addBodyPart(part2);
Finally, this MimeMultipart object is attached to the actual message and delivered using the following code:
msg.setContent(multipart );
Transport.send(msg);
The complete source code (EmailWithAttchment.java) is given below:
// EmailWithAttchment.java import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
class EmailWithAttachment { public static void main(String [] args) {
String to = “usr.some@gmail.com”;
final String user = “usr.some@gmail.com”;
final String password = “some.usr”;
String mailHost = “smtp.gmail.com”;
Properties props = new Properties();
props.setProperty(“mail.smtp.host”, mailHost);
props.put(“mail.smtp.auth”, “true”);
props.put(“mail.smtp.starttls.enable”, “true”);
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user,password);
}
});
//session.setDebug(true);
try{
MimeMessage msg = new MimeMessage(session);
msg.addRecipients(Message.RecipientType.TO,to);
msg.setSubject(”Mail with attachment”);
Multipart multipart = new MimeMultipart();
MimeBodyPart parti = new MimeBodyPart();
MimeBodyPart part2 = new MimeBodyPart();
//parti.setContent(”This mail has an attachment.”, ”text/plain”);
parti.setText(”This mail has an attachment.”);
String filename = ”EmailWithAttachment.java”;
//DataSource source = new FileDataSource(filename);
//DataHandler dh = new DataHandler(source);
//part2.setDataHandler(dh);
//part2.setFileName(filename);
part2.attachFile(filename);
multipart.addBodyPart(parti);
multipart.addBodyPart(part2);
msg.setContent(multipart );
Transport.send(msg);
System.out.println(”msg sent….”);
}catch (Exception e) {e.printStackTrace();}
}
}
5. Compiling the Program
This program uses javax.activation package. If you are using Java SE earlier than 6, then download javax.activation.jar.zip file from the following link
http://www.java2s.com/Code/Jar/j/Downloadjavaxactivationjar.htm
The, javax.activation.jar.zip file contains a single javax.activation.jar file. Unzip and put javax.activation.jar file in E:Netmaii directory. Use the following command to compile:
javac -cp javax.mail.jar,•javax.activation.jar;. EmailWithAttachment.java
Note that, Java SE 6 or later already has an activation package included. So, there is no need to download the jar file separately. Use the following command to compile:
javac -cp javax.mail.jar;. EmailWithAttachment.java
A sample output is shown in Figure 15.5:
Figure 15.6: shows a snapshot of Gmail interface that indicates that a mail arrived with an attachment.
Google and the Google logo are registered trademarks of Google Inc., used with permission.
Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.