现在的位置: 首页 > 综合 > 正文

JavaMail FAQ

2013年06月21日 ⁄ 综合 ⁄ 共 40269字 ⁄ 字号 评论关闭

General

 

Installation and Configuration

 

Programming

 

Reading mail, IMAP

 

Sending mail, SMTP

 

POP3

 

JavaMail in servlets

 

JavaMail in applets

 

 

 

 

General

 

Q: What is the JavaMail API?
A: The JavaMail API is a set of abstract APIs that model a mail system. The API provides a platform independent and protocol independent framework to build Java technology based email client applications. The JavaMail API provides facilities for reading and sending email. Service providers implement particular protocols. Several service providers are included with the JavaMail API package; others are available separately. The JavaMail API is implemented as a Java optional package that can be used on JDK 1.1.6 and later on any operating system. The JavaMail API is also a required part of the Java 2 Platform, Enterprise Edition (J2EE).

Q: How do I get an implementation of the JavaMail API?
A: Sun provides a royalty-free reference implementation, in binary form, that developers may use and ship. The reference implementation includes the core JavaMail packages and IMAP, POP3, and SMTP service providers.

Q: How do I send feedback or comments?
A: Send email to javamail@Sun.COM. Also consider joining our low-volume announce mailing list javamail-announce@java.sun.com. Instructions on how to join are in our web page at http://java.sun.com/products/javamail

Q: Where is javax.activation?
A: javax.activation is part of the JavaBeans Activation Framework (JAF). The JAF is part of the JavaBeans "Glasgow" specification (see http://java.sun.com/beans/glasgow/jaf.html). The JavaMail API uses the JAF for data content handling.

Q: What JDK does JavaMail API need?
A: The JavaMail API requires JDK/JRE 1.1.x or higher. We have tested this implementation with Sun Microsystems JDK 1.1.6 through JDK 1.1.7 on Solaris SPARC, Microsoft Windows 95/NT, and RedHat Linux 4.2. We have also tested with the Java 2 SDK, Standard Edition (J2SE SDK) versions 1.2, 1.3, and 1.4 on Solaris SPARC. The JavaMail APIs are a Java optional package, they are not part of the core J2SE but are included in J2EE. See http://java.sun.com/j2se for more information about JDK 1.1 and J2SE.

Q: Where can I find a version of JavaMail for my favorite operating system?
A: JavaMail is completely written in Java and will run on any operating system that supports the required version of the JDK. No special version is needed for different operating systems.

Q: Do the JavaMail APIs work in web browsers?
A: We have successfully run JavaMail 1.3 in Netscape and Internet Explorer.

Q: Can I use JavaMail to read mail from my web mail account (such as Yahoo or Hotmail)?
A: It depends. Many web-based email services provide access only using a browser with HTTP. These services cannot be accessed using JavaMail. If the service also provides POP3 or IMAP access, JavaMail can probably be used to access it. Contact your web email service provider for details. Also, see the JHTTPMail project for an open source provider for JavaMail that provides access to Hotmail. Another helpful tool is MrPostman, a proxy server that provides POP3 access to Hotmail and Yahoo! Mail, available at http://mrbook.org/mrpostman/

Q: What is IMAP?
A: IMAP stands for Internet Message Access Protocol. It is a method of accessing electronic mail messages stored on a (possibly shared) mail server. In other words, it permits a "client" email program to access remote message stores as if they were local. IMAP is defined by RFC2060. For more information, see http://www.imap.org/

Q: What is SMTP?
A: SMTP stands for Simple Mail Transfer Protocol. It is used to transfer RFC822-style messages between different mail hosts as well as to submit new messages to a host for delivery. SMTP is in very wide use (it originated in 1982) and is defined by RFC821.

Q: What is MIME?
A: MIME and RFC822 are the standards for describing email messages that are sent across the Internet. The javax.mail.internet subpackage (which is part of the JavaMail APIs) provides a complete implementation of these two packages. MIME is specified by the following RFCs: RFC2045, RFC2046, RFC2047.

Q: What is POP3?
A: POP3 stands for Post Office Protocol version 3. POP3 is a very limited protocol for accessing a single mailbox. It is much less capable than IMAP. POP3 is very widely used and is defined by RFC1939.

Q: What about support for MAPI, NNTP, Lotus Notes, and other service providers?
A: We have no current plans to implement any of these providers. However, the architecture of the JavaMail APIs provides for being able to easily plug-in third-party service providers. It is our hope that third-parties will embrace the JavaMail APIs by writing providers for other standard and proprietary protocols. See our Third Party Products page for the latest list of such providers.

Q: How do I store mail messages on my local disk?
A: A "local store provider" can be used to store mail messages on a local disk. The JavaMail APIs do not include such a provider but several are available from third parties for different local store formats such as MH and Mbox. See our Third Party Products page for the latest list of such providers.

Q: Where do I find documentation on the Sun protocol providers?
A: The Sun protocol providers for IMAP, POP3, and SMTP support many features that are not part of the JavaMail API specification. The documentation for these protocol providers is included in the JavaMail 1.3 download package in javadoc format in the docs/javadocs directory. The package level documentation for each protocol provider package describes the properties that are supported by the protocol proivder. In addition, the protocol providers include some classes and methods that applications can use to take advantage of provider-specific features. Note that use of these properties, classes, and methods renders a program non-portable; it may only work with Sun's implementation of the JavaMail API.

Q: Is the JavaMail API implementation completely free? Can I ship it along with my product?
A: Yes. The current release of the JavaMail API implementation, is completely free and you can include it in your product. This release includes IMAP, POP3, and SMTP providers as well. Please do read the license and ensure that you understand it. (The license is available after clicking the Download button on the download page.) The JavaBeans Activation Framework is also free for use under a similar license.

Q: Can I get the source code for the JavaMail API implementation?
A: The JavaMail API reference implementation source code is now available as a part of J2EE under the SCSL license. Download it here.

Q: Is JavaMail Y2K compliant?
A: Yes. Sun's JavaMail implementation is Option-3 Y2K compliant. Please see the NOTES.txt file in the JavaMail package for more information.

Q: The answer to my question isn't here, where else should I look?
A: In addition to the JavaMail API spec and javadocs (available both from our main web page and included in the download bundle), don't forget to check the README.txt and NOTES.txt files included with the JavaMail API package for additional important information.

The javamail-interest mailing list is another source of information. See our main web page for instructions on how to subscribe and a pointer to the archives.

The Java Developer Connection maintains a JavaMail forum, see http://forum.java.sun.com. Note that the JavaMail team monitors the javamail-interest mailing list, but does not monitor the JavaMail forum.

jGuru also maintains a JavaMail FAQ, which you'll find at http://www.jguru.com/faq/JavaMail.

Installation and Configuration

 

Q: How do I install the JavaMail API implementation?
A: Unzip the distribution zip file and edit your CLASSPATH environment variable to include the mail.jar file that was included with the JavaMail API distribution. You will also need an implementation of the JavaBeans Activation Framework (see below). See the README file (in the distribution) for additional details and examples.

Q: Does JavaMail include all the necessary mail servers?
A: No, the JavaMail API package does not include any mail servers. To use the JavaMail API package, you'll need to have access to an IMAP or POP3 mail server (for reading mail) and/or an SMTP mail server (for sending mail). These mail servers are usually provided by your Internet Service Provider or are a part of your organization's networking infrastructure. If you don't have access to such a mail server, see below.

Q: Where can I get the necessary mail servers?
A: Sun Java System Messaging Server is available for Solaris and Windows platforms. The University of Washington IMAP server supports multiple platforms (UNIX, Windows 32bit, etc). Get the source code from ftp://ftp.cac.washington.edu/imap/imap.tar.Z. There are several free, all Java mail servers available, including Apache James and Java Email Server. Many other vendors provide mail servers supporting Internet standards. More information can be obtained from The IMAP Connection and Internet Mail Consortium.

Q: What host name, user name, or password should I use?
A: We do not provide a mail server for you to use. You must use your own mail server, or one provided by your Internet Service Provider or the company you work for. Your network administrator can give you the information necessary to configure JavaMail to work with your mail server.

Q: How do I configure JavaMail to work through my proxy server?
A: Most proxy servers support only the HTTP protocol. JavaMail doesn't use the HTTP protocol to read or send mail. One of the major reasons for using a proxy server is to allow HTTP requests from within a corporate network to pass through a corporate firewall. The firewall will typically block most access to the Internet, but will allow requests from the proxy server to pass through. In addition, a mail server inside the corporate network will perform a similar function for email, accepting messages via SMTP and forwarding them to their ultimate destination on the Internet, and accepting incoming messages and sending them to the appropriate internal mail server.

If your proxy server supports the SOCKS V4 or V5 protocol (http://www.socks.nec.com/aboutsocks.html, RFC1928) and allows anonymous connections, you can tell the Java runtime to direct all TCP socket connections to the SOCKS server. See http://java.sun.com/j2se/1.4/docs/guide/net/properties.html for the latest documentation of the socksProxyHost and socksProxyPort properties. These are system-level properties, not JavaMail session properties. They can be set from the command line when the application is invoked, for example: java -DsocksProxyHost=myproxy .... This facility can be used to direct the SMTP, IMAP, and POP3 communication from JavaMail to the SOCKS proxy server. Note that setting these properties directs all TCP sockets to the SOCKS proxy, which may have negative impact on other aspects of your application.

Without such a SOCKS server, if you want to use JavaMail to directly access mail servers outside the firewall, the firewall will need to be configured to allow such access. A simple HTTP proxy web server is not sufficient.

Q: How do I set my CLASSPATH on Windows NT?
A: Detailed instructions are available here

Q: While trying to run my program on Linux I get a very strange error message and the program fails. What did I do wrong?
A: The error message often looks something like this:

Exception in thread "main"
java.lang.VerifyError:(Class:com/sun/mail/pop3/POP3Store,
method: finalize Signature :()V)
Illegal use of nonvirtual function call

 

The problem is due to a buggy version of the unzip command used to unzip the JavaMail download package on Linux. The unzip command corrupts the mail.jar file. Get a newer version of the unzip command, or use the JDK's jar command to unzip the package.

 

Q: How do I use JavaMail in an application run under a SecurityManager; what permissions must I grant to the application and to JavaMail?
A: When using JavaMail in a JDK 1.2 (or later) environment with a SecurityManager, JavaMail will sometimes fail to read the configuration files in the mail.jar file. The JavaBeans Activation Framework may have the same problem reading configuration files from the activation.jar file. These default configuration files are stored as "resource" files in the META-INF directory in the jar file.

There are a number of debugging techniques that can be used to determine if this is the problem. Setting the Session property "mail.debug" to true (or calling session.setDebug(true)) will cause JavaMail to print debugging messages as it attempts to load each configuration file. A message of the form "DEBUG: can't load default providers file" indicates that this problem might exist. Similarly, setting the System property "javax.activation.debug" to "true" (e.g., by running the program using "java -Djavax.activation.debug=true ...") will cause JAF to print debugging messages as it attempts to load each resource file. Finally, the JDK can produce helpful debugging output by setting the system property "java.security.debug" to "access:failure" (e.g., by running the program using "java -Djava.security.debug=access:failure ...").

In addition to the permissions necessary to read the configuration files, the application (and JavaMail) will also need permission to connect to the mail servers it uses. If the application uses System properties to configure JavaMail (e.g., by passing the Properties object returned from System.getProperties() to the Session constructor, as many of the JavaMail demo programs do), it will also need permission to use the System Properties object. Alternatively, the application can use its own Properties object and be sure to set the "mail.from" property or the "mail.user" and "mail.host" properties (see the InternetAddress.getLocalAddress() method).

To allow an application to use JavaMail under a JDK 1.2 SecurityManager, the application, JavaMail, and JAF will need permissions such as the following (be sure to replace the host and path names with appropriate values); add these to the security policy file used by the application:

grant {
    // following two permissions allow
    // access to default config files
    permission java.io.FilePermission
		"/path/to/mail.jar", "read";
    permission java.io.FilePermission
		"/path/to/activation.jar", "read";
    // following to use SMTP
    permission java.net.SocketPermission
		"SMTPHOST:25", "connect,resolve";
    // following to use IMAP
    permission java.net.SocketPermission
		"IMAPHOST:143", "connect,resolve";
    // following to use POP3
    permission java.net.SocketPermission
		"POP3HOST:110", "connect,resolve";
    // following needed if System.getProperties() is used
    permission java.util.PropertyPermission
		"*", "read,write";
};


Q: How do I configure my web server to run the JavaMail demo servlet?
A: Instructions for the following web servers are available here:

 

Q: When using JavaMail in my servlet, it is unable to find any of the JavaMail classes. I've added mail.jar to the server's CLASSPATH.
A: It is often necessary to completely restart the web server when changing the CLASSPATH.

Q: My servlet can find the JavaMail classes, but JavaMail complains that it can't find a service provider for "smtp" or "imap" or address type "rfc822".
A: Usually this is because JavaMail can't access the configuration files in mail.jar, possibly because of a security permission problem; see this item for more details. Also, make sure that you haven't extracted the mail.jar contents; you should include the unmodified mail.jar file in the server's CLASSPATH.

Q: Where can I find jws.jar? I've installed Java Web Server 2.0 and am trying to run the JavaMailServlet. The README file instructs me to add jws.jar to my CLASSPATH.
A: jws.jar is no longer shipped with Java Web Server (as it was in previous releases) and thus doesn't need to be added to CLASSPATH. Simply add mail.jar and activation.jar to your CLASSPATH before starting the Java Web Server.

Programming

 

Q: Where can I learn the basics about Internet email that I'll need to know to program JavaMail effectively?
A: See one of the books referenced on our web page for a good background on Internet email, MIME, SMTP, IMAP, POP3, etc.

Q: How do I debug my application that uses JavaMail APIs?
A: Turn debug mode on by invoking the method setDebug(true) on the Session object in your code. That will cause debug information to be printed to the console, including a protocol trace. If you think that you found a bug in JavaMail, send us this trace along with a test case that reproduces the problem, the platform you are using, the version of the JDK you are using, and the name and version of the mail servers (IMAP, SMTP) that you are using.

Q: How do I send a message with an attachment?
A: A message with attachments is represented as a MIME multipart message where the first part is the main body of the message and the other parts are the attachments. There are numerous examples showing how to construct such a message in the demo programs included in the JavaMail download package.

Q: How do I read a message with an attachment and save the attachment?
A: As described above, a message with an attachment is represented in MIME as a multipart message. In the simple case, the results of the Message object's getContent method will be a MimeMultipart object. The first body part of the multipart object wil be the main text of the message. The other body parts will be attachments. The msgshow.java demo program shows how to traverse all the multipart objects in a message and extract the data of each of the body parts. The getDisposition method will give you a hint as to whether the body part should be displayed inline or should be considered an attachment (but note that not all mailers provide this information).

To save the data in a body part into a file (for example), use the getInputStream method to access the attachment content and copy the data to a FileOutputStream.

Note that there are also more complicated cases to be handled as well. For example, some mailers send the main body as both plain text and html. This will typically appear as a multipart/alternative content (and a MimeMultipart object) in place of a simple text body part. Also, messages that are digitally signed or encrypted are even more complex. Handling all these cases can be challenging. Please refer to the various MIME specifications and other resources listed on our main page.

Q: How do I tell if a message has attachments? [new!]
A: In the simplest case, a message of MIME type multipart/mixed with more than one body part is likely a message with attachments. As described above, there are more complex cases to consider as well. In particular, messages may have arbitrary nesting of multipart/mixed and multipart/alternative parts and may include multipart/related parts for embedded HTML and multipart/signed and/or multipart/encrypted parts for secure messages. It's up to you to decide how many of these cases you want to handle in your application before deciding that a message has an attachment. Most applications take a very simple approach to this and handle only a few of the most commonly seen cases.

Q: How do I create a multipart message with a part of any MIME type I choose? [new!]
A: The JavaMail API includes builtin support for the most common MIME types, but to create a message that includes data in a MIME type that JavaMail does not already understand, you'll need to supply that data to JavaMail in a byte stream format. The ByteArrayDataSource.java class in the demo directory of the JavaMail download package can help. This class will take a String, byte array, or InputStream and create a DataSource object that you can use as follows:

    MimeBodyPart mbp = new MimeBodyPart();
    String data = "any ASCII data";
    DataSource ds = new ByteArrayDataSource(data, "application/x-any");
    mbp.setDataHandler(new DataHandler(ds));


You can specify any MIME type that you want. The MimeBodyPart object can then be added to a MimeMultipart object in the usual way.

Note that if you create a ByteArrayDataSource with an InputStream, it first copies all of the data in the stream into memory. This is necessary because a DataSource needs to be able to supply multiple InputStream objects so that JavaMail can read the data once to determine what Content-Transfer-Encoding is appropriate, and then read the data again to include the data in the message.

Q: What is "disconnected support"?
A: A mail client supporting disconnected operation will allow the user to access messages in a remote message store (e.g., IMAP), cache (parts of) some of those messages locally, and break the connection to the server. While in this disconnected state, the mail client can access the messages that have been cached, possibly deleting them or saving them to other folders. When the mail client next connects to the remote message store, the changes made locally will be synchronized with the remote store. Similarly, disconnected support may allow the client to "send" messages when there is no connection to the server, with the messages being queued until a connection to the server is available. See also RFC1733.

Q: How do I support disconnected operation using the JavaMail APIs?
A: The JavaMail API specification defines interfaces that can be used by a mail client to support disconnected operation. Our IMAP provider implements these interfaces (the UIDFolder interfaces).

Q: How do I send secure email using the JavaMail APIs?
A: The JavaMail APIs currently have no support for sending or receiving secure email. The architecture of the JavaMail APIs allows such support to be easily added later, by us or by third parties. Information on the current Email security standards (S/MIME and PGP) can be found at http://www.imc.org/smime-pgpmime.html.
Please browse our Third Party Products page for solutions from other vendors.

Q: The writeTo() method generates message text with lines that are neither the canonical MIME representation of the data (i.e., using CRLF to terminate lines), nor using the canonical line separator of my platform (e.g., "/n" on UNIX). How do I get either of these representations if I need them?
A: In either case you'll need to create an appropriate FilterOutputStream to hand to writeTo(). The FilterOutputStream will need to accept lines with any of the common line terminators and write out lines with only the desired line terminator. The following are examples of such filters. NewlineOutputStream converts to the local platform's line terminator and is useful when writing a message to a file. CRLFOutputStream converts to the MIME canonical CRLF line terminator and is useful when the canonical MIME format is needed (e.g., to compute a digital signature).

Q: Can I use the JavaMail APIs to implement a mail server?
A: The JavaMail API was not intended to help you implement a mail server. Nonetheless, some of the utility classes, such as the MIME message parsing classes, might be of use to you. In general you'll find that the JavaMail API errs on the side of "simple" instead of "robust". That's appropriate for a mail client, but a mail server would likely make different tradeoffs.

Q: Can I use the JavaMail APIs to add new user accounts to my mail server, remove user accounts from my mail server, or change the passwords for user accounts on my mail server?
A: The JavaMail API does not include any facilities for adding, removing, or changing user accounts. There are no standards in this area; every mail server handles this differently.

Q: Why doesn't the MimeMessage class implement Serializable so that I can serialize a message to disk and read it back later?
A: The JavaMail API was designed to layer on top of existing email systems, using existing message formats. The ability to use Java serialization was neither essential nor useful for such implementations, and thus was not considered a goal of the JavaMail API.

The hard part about serializing a Message is retaining the pointers to the Folder, Store, and Session. If you only want to save the content of the message, and not the object itself, the writeTo method of a message gives you everything you need. If you want to create an entire email system based on serialized messages, you should be able to subclass Message et. al. and implement Serializable in your subclass.

If you want to serialize other objects of your own that reference MimeMessages, the writeObject method of your object can use the writeTo method of MimeMessage, and the readObject method of your object can use the MimeMessage constructor that takes an InputStream. Your class will need to provide a Session when constructing the MimeMessage.

Q: How do I write a Service Provider?
A: Please read the Service Provider documentation for details. In general, if you want to write a Store provider, you subclass javax.mail.Store, javax.mail.Folder, possibly javax.mail.Message and a few others. For a Transport provider, you subclass javax.mail.Transport, possibly javax.mail.Message and a few others. Then you add the entry describing your provider to the javamail.providers registry. If you're interested in writing a service provider for a protocol or messaging system not currently supported by the JavaMail API implementation, please contact us at javamail@Sun.COM.

Q: I'm having trouble logging into my Microsoft Exchange server, even though I'm sure I'm using the correct username and password, what could I be doing wrong?
A: When logging in to Exchange you need to use a username that's more than your simple login name. For example, if your email address is "J.User@server.com", your Windows NT login name is "juser", your NT domain name is "dom", and your Exchange mailbox name is "Joe User", then you would need to use a username of "dom/juser/J.User" when logging in using JavaMail.

Q: How do I encode a binary file before sending it and how do I decode it when I receive it?
A: You don't need to! JavaMail will automatically determine an appropriate encoding to use for your message parts before sending the message, and will automatically decode message parts when reading them. The getInputStream method will return the decoded data.

Q: If I don't need to encode and decode attachments myself, when should I use the MimeUtility methods?
A: The MimeUtility methods are useful in cases that JavaMail doesn't handle automatically for you. One such case that occurs frequently is encoding of filenames. The base MIME spec does not allow header parameter values (such as the filename parameter) to be encoded in the same way that (e.g.) the Subject header may be encoded. This restricts parameter values, and thus filenames, to ASCII. However, some mailers actually do encode non-ASCII filenames using the MIME text encoding. Applications that wish to interoperate with such non-standard mailers can use the encodeText method to encode filenames before calling the MimeBodyPartsetFileName method, and can use the decodeText method to decode returned filenames.

Q: Even though JavaMail does all the encoding and decoding for me, I need to manually control the encoding for some body parts.
A: In the rare case that you need to control the encoding, there are several ways to override JavaMail's default behavior. A simple approach is as follows. After creating the entire message, call msg.saveChanges() and then use something like mbp.setHeader("Content-Transfer-Encoding", "base64") to force base64 encoding for the given body part.

Another approach is to subclass MimeBodyPart and override the updateHeaders method so that it first calls super.updateHeaders() and then sets the Content-Transfer-Encoding header as above.

Q: Why doesn't JavaMail properly encode and decode filenames in non-ASCII character sets?
A: The filename is stored as a parameter in MIME headers. Encoded filenames of the form =?ISO-8859-15?B?5OTkLUluZm8ucGRm?= are not part of the MIME spec. A filename of the form =?A?B?C?= is a perfectly valid filename, not an incorrectly encoded filename. JavaMail does not encoded and decode filenames because doing so would violate the MIME spec.

The base MIME spec does not allow for encoding parameters. RFC 2231 defines a new way to include encoded paramters, including filenames, in MIME headers. It is not compatible with the de facto way that many applications illegally encode filenames. Supporting RFC 2231 would not allow JavaMail to interoperate with these existing programs. As far as I know, very few existing programs support RFC 2231.

If you choose to violate the MIME spec, in order to interoperate with other programs that also violate the MIME spec, JavaMail gives you all the tools you need to do so.

The workaround for encoding a filename is simple:

mbp.setFileName(MimeUtility.encodeText(filename));

The workaround for decoding a filename is equally simple:

String filename = MimeUtility.decodeText(part.getFileName());

Reading mail, IMAP

 

Q: I tried running your demos against my IMAP server, but I get an error.
A: First verify that you indeed have an email account on the IMAP server. Check with your system administrator about it. Turn debug mode on, by invoking the method setDebug(true) on the session object in your code. This will cause the IMAP protocol trace to be dumped on your screen. Send us this trace. The trace will be very useful to us for identifying the problem. If you can, please send us vendor information about your IMAP server.

Q: The IMAP provider seems to lose data when I fetch messages with large attachments.
A: This is due to bugs in the partial fetch implementation of your IMAP server. To workaround this server bug, set the "mail.imap.partialfetch" property to false. Refer to NOTES.txt from the JavaMail package for more information.

Q: Does the IMAP provider cache the retrieved data?
A: The IMAP provider fetches the data for a message from the server only when necessary. (The javax.mail.FetchProfile can be used to optimize this). The header and bodystructure information, once fetched, is always cached within the Message object. However, the content of a bodypart is not cached. So each time the content is requested by the client (either using getContent() or using getInputStream()), a new FETCH request is issued to the server. The reason for this is that the content of a message could be potentially large, and if we cache this content for a large number of messages, there is the possibility that the system may run out of memory soon since the garbage collector cannot free the referenced objects. Clients should be aware of this and must hold on to the retrieved content themselves if needed.

Q: I want to move messages between folders. Should I use appendMessages() or copyMessages()?
A: Use copyMessages() if the messages to be copied/moved belong to the folder on which this method is being invoked. This is because some implementations can optimize this operation if the source and destination folder belong to the same backend Store. Otherwise, use appendMessages().

Q: Retrieving large message bodies seems inefficient at times.
A: If you are using the Sun IMAP provider, you could try increasing the mail.imap.fetchsize property (the current default is 16k). This will cause data to be fetched from the server is larger chunks. Note that you risk the possibility of the JVM running out of memory when you do this.

Q: I get OutOfMemory errors when loading this large binary attachement.
A: Increase the maximum JVM heapsize at startup. Use the "-mx" option if using the standard JVM from Sun. Don't keep references to the "content" of messages not being used. In certain cases, you could try streaming the message content (using getInputStream()) as raw bytes, use and then discard the used data chunks.

Q: Why do I get the UnsupportedDataTypeException when I invoke getContent() on a bodypart?
A: The getContent() method returns a Java object that represents the bodypart content. For this to work, a JAF DataContentHandler corresponding to the content's MIME type must be registered. Otherwise, the UnsupportedDataTypeException will be thrown. In this case, you can use the getInputStream() method to retrieve the content as a stream of bytes. See the JAF docs for details on how to create and register your own DataContentHandlers.

Q: Why do I get the UnsupportedEncodingException when I invoke getContent() on a bodypart that contains text data?
A: Textual bodyparts (i.e., bodyparts whose type is "text/plain", "text/html", or "text/xml") return Unicode String objects when getContent() is used. Typically, such bodyparts internally hold their textual data in some non Unicode charset. JavaMail (through the corresponding DataContentHandler) attempts to convert that data into a Unicode string. The underlying JDK's charset converters are used to do this. If the JDK does not support a particular charset, then the UnsupportedEncodingException is thrown. In this case, you can use the getInputStream() method to retrieve the content as a stream of bytes. Example:

    String s;
    if (part.isMimeType("text/plain")) {
	try {
	    s = part.getContent();
	} catch (UnsupportedEncodingException uex) {
	    InputStream is = part.getInputStream();
	    /*
	     * Read the input stream into a byte array.
	     * Choose a charset in some heuristic manner, use
	     * that charset in the java.lang.String constructor
	     * to convert the byte array into a String.
	     */
	    s = convert_to_string(is);
	} catch (Exception ex) {
	    // Handle other exceptions appropriately
	}
    }


Sending mail, SMTP

 

Q: How do I reply to a message?
A: To reply to a message, use the reply method on the Message object. This method will return a new object with the headers set appropriately for a reply. You'll need to supply the content of the message yourself.

Q: How do I forward a message?
A: The approach used to forward a message depends on how you want to present the forwarded message. It's straightforward to create a new MimeMessage, address it appropriately, and attach an existing message as an attachment to the new message. To attach the original message to the new message, use code such as:

    MimeBodyPart mbp = new MimeBodyPart();
    mbp.setContent(forwardedMsg, "message/rfc822");
    mp.addPart(mbp);


If instead you want to create the new message with the text of the original message included in the new message, perhaps indented by "> ", you'll need to extract the data of the orginal message's main body and process it accordingly. You might also want to take other attachments from the original message and add them to the new message.

Q: How do I send HTML mail?
A: There are a number of demo programs included with the distribution that show how to send HTML mail. If you want to send a simple message that has HTML instead of plain text, see the sendhtml.java program in the demo directory. If you want to send an HTML file as an attachment, see the sendfile.java example that shows how to send any file as an attachment.

Q: How do I send mail with formatted text using different fonts and colors?
A: The simplest approach is to send a message using HTML text. See above.

Q: How do I send mail with both plain text as well as HTML text so that each mail reader can choose the format appropriate for it?
A: You'll want to send a MIME multipart/alternative message. You construct such a message essentially the same way you construct a multipart/mixed message, using a MimeMultipart object constructed using new MimeMultipart("alternative"). You then insert the text/plain body part as the first part in the multpart and insert the text/html body part as the second part in the multipart. See RFC2046 for details of the structure of such a message.

Q: How do I send mail HTML mail that includes images?
A: The simplest approach is to send HTML text with image tags that reference images on a public web site. In this approach the images aren't actually included in the message, and so won't be visible if the user is not connected to the Internet when they read the message.

Alternatively, you can construct a MIME multipart/related message. See RFC2387 for details of the structure of such a message.

Q: What's the difference between the Transport methods send and sendMessage?
A: The send() method is a static method and can be used without needing an instance of a Transport object. It is intended for the common, simple case of sending a single message using the default transport. Internally, the send() method will first call the saveChanges() method on the message. It will then create an appropriate new Transport object, call the Transport's connect() method, call the Transport's sendMessage() method to actually send the message, call the Transport's close() method, and finally abandon the new instance of the Transport object to be collected by the garbage collector. (Actually, it's rather more complicated than that, but that's the general idea.)

As you can see, the static send() convenience method is built on the more general per-instance sendMessage() method. There are a number of reasons for an application to use the sendMessage() method directly. The most common reasons are to improve performance by sending more than one message during a single connection, or to manually manage the connection so as to provide authentication information. The most common mistake made when using the sendMessage() method is forgetting to call the saveChanges() method on the message to be sent.

Q: I need to authenticate to my SMTP server so I call trans.connect(host, user, password) and then trans.send(msg) to send the message, but it's not working.
A: You should call msg.saveChanges() and then trans.sendMessage(msg, addrs) to send the message. As described above, the send method is a static convenience method that acquires its own Transport object and creates its own connection to use for sending; it does not use the connection associated with any Transport object through which it is invoked. And of course don't forget to set the mail.smtp.auth property to true to enable SMTP authentication!

Q: I modified this message, but the headers do not reflect the changes.
A: You should call saveChanges() after you create a new message or modify an existing message. This will cause the headers to be reset and reflect your changes. Note that the Transport.send(Message) method calls this implicitly. So if all you are doing is sending the modified message, you can skip calling saveChanges() yourself. saveChanges() is a potentially expensive operation (especially for large or deeply nested messages), so call it only when needed.

Q: I'm using the sendMessage() method to send my message but the message comes out with strange looking lines before and after my text, and my attachments appear in the body of my message.
A: The lines often look something like

--928176543.952742998030.JavaMail.name@host

As above, you must call the saveChanges() method after you create a new message and before you send the message when using the Transport.sendMessage() method. The static Transport.send() method automatically calls the Message.saveChanges() method for you.

Q: I set a particular value for the Message-ID header of my new message. But when I send this message, that header is rewritten.
A: saveChanges() will set a new value for the Message-ID field, overwriting any value you set yourself. If you need to set your own Message-ID and have it retained, you will have to create your own MimeMessage subclass, override the updateHeaders() method and use an instance of this subclass.

class MyMessage extends MimeMessage {
    ...

    protected void updateHeaders() throws MessagingException {
	super.updateHeaders();
	setHeader("Message-ID", "my-message-id");
    }
    ...
}


Q: Why do I get an UnsupportedDataTypeException when sending this new message that I created?
A: You probably set some content for your message using the setContent(Object o, String type) method. For this to work, there must be a JAF DataContentHandler registered for the given "type". If not, you will get the UnsupportedDataTypeException. See the JAF documents () for more information. Q: How can I explicitly set the SMTP FROM: attribute when sending a message?
A: The mail.smtp.from property can be used to set the SMTP FROM: attribute. If this property if absent, the message's From attribute is used. If multiple threads need to send mail simultaneously, and each needs to set the From attribute, each thread should use its own Session object with its own Properties object.

抱歉!评论已关闭.