Internet Mail in JavaMail

来源:互联网 发布:淘宝县级运营中心查询 编辑:程序博客网 时间:2024/05/01 08:54

Internet Mail


The JavaMail specification does not define any implementation. However, the API does include a set of classes that implement Internet Mail standards. Although not part of the specification, these classes can be considered part of the JavaMail package. They show how to adapt an existing messaging architecture to the JavaMail framework.

These classes implement the Internet Mail Standards defined by the RFCs listed below:

  • RFC822 (Standard for the Format of Internet Text Messages)
  • RFC2045, RFC2046, RFC2047 (MIME)

    RFC822 describes the structure of messages exchanged across the Internet. Messages are viewed as having a header and contents. The header is composed of a set of standard and optional header fields. The header is separated from the content by a blank line. The RFC specifies the syntax for all header fields and the semantics of the standard header fields. It does not however, impose any structure on the message contents.

The MIME RFCs 2045, 2046 and 2047 define message content structure by defining structured body parts, a typing mechanism for identifying different media types, and a set of encoding schemes to encode data into mail-safe characters.

The Internet Mail package allows clients to create, use and send messages conforming to the standards listed above. It gives service providers a set of base classes and utilities they can use to implement Stores and Transports that use the Internet mail protocols.

The JavaMail MimePart interface models an entity as defined in RFC2045, Section 2.4. MimePart extends the JavaMail Part interface to add MIME-specific methods and semantics. The MimeMessage and MimeBodyPart classes implement the MimePart interface. The following figure shows the class hierarchy of these classes.
这里写图片描述


The MimeMessage Class

The MimeMessage class extends Message and implements MimePart. This class implements an email message that conforms to the RFC822 and MIME standards.

The MimeMessage class provides a default constructor that creates an empty MimeMessage object. The client can fill in the message later by invoking the parse method on an RFC822 input stream. Note that the parse method is protected, so that only this class and its subclasses can use this method. Service providers implementing ’light-weight’ Message objects that are filled in on demand can generate the appropriate byte stream and invoke the parse method when a component is requested from a message. Service providers that can provide a separate byte stream for the message body (distinct from the message header) can override the getContentStream method.

The client can also use the default constructor to create new MimeMessage objects for sending. The client sets appropriate attributes and headers, inserts content into the message object, and finally calls the send method for that MimeMessage object.

This code sample creates a new MimeMessage object for sending.

MimeMessage m = new MimeMessage(session);// Set FROM:m.setFrom(new InternetAddress("jmk@Sun.COM"));// Set TO:InternetAddress a[] = new InternetAddress[1];a[0] = new InternetAddress("javamail@Sun.COM");m.setRecipients(Message.RecipientType.TO, a);// Set contentm.setContent(data, "text/plain");// Send messageTransport.send(m);

The MimeMessage class also provides a constructor that uses an input stream to instantiate itself. The constructor internally invokes the parse method to fill in the message. The InputStream object is left positioned at the end of the message body.

InputStream in = getMailSource(); // a stream of mail messages        MimeMessage m = null;        for (;;) {            try {                m = new MimeMessage(session, in);            } catch (MessagingException ex) {                // reached end of message stream                break;            }        }

MimeMessage implements the writeTo method by writing an RFC822-formatted byte stream of its headers and body. This is accomplished in two steps: First, the MimeMessage object writes out its headers; then it delegates the rest to the DataHandler object representing the content.


The MimeBodyPart Class

The MimeBodyPart class extends BodyPart and implements the MimePart interface. This class represents a Part inside a Multipart. MimeBodyPart implements a Body Part as defined by RFC2045, Section 2.5.

The getBodyPart(int index) returns the MimeBodyPart object at the given index. MimeMultipart also allows the client to fetch MimeBodyPart objects based on their Content-IDs.

The addBodyPart method adds a new MimeBodyPart object to a MimeMultipart as a step towards constructing a new multipart MimeMessage.


The MimeMultipart Class

The MimeMultipart class extends Multipart and models a MIME multipart content within a message or a body part.

A MimeMultipart is obtained from a MimePart containing a ContentType attribute set to multipart, by invoking that part’s getContent method.

The client creates a new MimeMultipart object by invoking its default constructor. To create a new multipart MimeMessage, create a MimeMultipart object (or its subclass); use set methods to fill in the appropriate MimeBodyParts; and finally, use setContent(Multipart) to insert it into the MimeMessage.

MimeMultipart also provides a constructor that takes an input stream positioned at the beginning of a MIME multipart stream. This class parses the input stream and creates the child body parts.

The getSubType method returns the multipart message MIME subtype. The subtype defines the relationship among the individual body parts of a multipart message. More semantically complex multipart subtypes are implemented as subclasses of MimeMultipart, providing additional methods that expose specific functionality.

Note that a multipart content object is treated like any other content. When parsing a MIME Multipart stream, the JavaMail implementation uses the JAF framework to locate a suitable DataContentHandler for the specific subtype and uses that handler to create the appropriate Multipart instance. Similarly, when generating the output stream for a Multipart object, the appropriate DataContentHandler is used to generate the stream.


The MimeUtility Class

MimeUtility is a utility class that provides MIME-related functions. All methods in this class are static methods. These methods currently perform the functions listed below:

Content Encoding and Decoding

Data sent over RFC 821/822-based mail systems are restricted to 7-bit US-ASCII bytes. Therefore, any non-US-ASCII content needs to be encoded into the 7-bit US-ASCII (mail-safe) format. MIME (RFC 2045) specifies the “base64” and “quoted-printable” encoding schemes to perform this encoding. The following methods support content encoding:

  • The getEncoding method takes a DataSource object and returns the Content-Transfer-Encoding that should be applied to the data in that DataSource object to make it mail-safe.
  • The encode method wraps an encoder around the given output stream based on the specified Content-Transfer-Encoding. The decode method decodes the given input stream, based on the specified Content-Transfer-Encoding.

Header Encoding and Decoding

RFC 822 restricts the data in message headers to 7bit US-ASCII characters. MIME (RFC 2047) specifies a mechanism to encode non 7bit US-ASCII characters so that they are suitable for inclusion in message headers. This section describes the methods that enable this functionality.

The header-related methods (getHeader, setHeader) in Part and Message operate on Strings. String objects contain (16 bit) Unicode characters.

Since RFC 822 prohibits non US-ASCII characters in headers, clients invoking the setHeader() methods must ensure that the header values are appropriately encoded if they contain non US-ASCII characters.

The encoding process (based on RFC 2047) consists of two steps:

  • Convert the Unicode String into an array of bytes in another charset. This step is required because Unicode is not yet a widely used charset. Therefore, a client must convert the Unicode characters into a charset that is more palatable to the recipient.
  • Apply a suitable encoding format that ensures that the bytes obtained in the previous step are mail-safe.

The encodeText method combines the two steps listed above to create an encoded header. Note that as RFC 2047 specifies, only “unstructured” headers and user-defined extension headers can be encoded. It is prudent coding practice to run such header values through the encoder to be safe. Also note that the encodeText method encodes header values only if they contain non US-ASCII characters.

The reverse of this process (decoding) needs to be performed when handling header values obtained from a MimeMessage or MimeBodyPart using the getHeader set of methods, since those headers might be encoded as per RFC 2047. The decodeText method takes a header value, applies RFC 2047 decoding standards, and returns the decoded value as a Unicode String. Note that this method should be invoked only on “unstructured” or user-defined headers. Also note that decodeText attempts decoding only if the header value was encoded in RFC 2047 style. It is advised that you always run header values through the decoder to be safe.


The ContentType Class

The ContentType class is a utility class that parses and generates MIME content-type headers.

To parse a MIME content-Type value, create a ContentType object and invoke the toString method.

The ContentType class also provides methods that match Content-Type values.

The following code fragment illustrates the use of this class to extract a MIME parameter.

String type = part.getContentType();ContentType cType = new ContentType(type);if (cType.match("application/x-foobar"))    String color = cType.getParameter("color");

This code sample uses this class to construct a MIME Content-Type value:

ContentType cType = new ContentType();cType.setPrimaryType("application");cType.setSubType("x-foobar");cType.setParameter("color", "red");String contentType = cType.toString();

REF:JavaMailTM API Design Specification Version 1.5

0 0
原创粉丝点击