How do you send HTML mail with images?

John Zukowski

The basic process of sending an HTML message is described in http://www.jguru.com/jguru/faq/view.jsp?EID=43236. Basically, you need to set the content type for the HTML part.

As far as the images go... you are actually better off leaving them on your server and letting the user's mail tool take care of pulling them across when viewing the HTML file. While yes you can include the images as attachments with the HTML body, what the mail tool does with them you have no control over. For instance, if all attachment files are saved to the same directory (like Eudora) then you must name the image files uniquely in order for the mail tool to be sure to display YOUR images and not some other image that the user received from you or someone else.

Remember to make your image URLs absolute, not relative, too. As relative ones will not resolve properly from the mail client.

If you really want to send them along with the message... You'll need to create a "multipart/related" message. One of the parts will be the HTML part which refers to the other parts which are the image parts. An RFC that contains information about multipart/related messages is available at http://www.faqs.org/rfcs/rfc2387.html.

To reference the other parts, the URL will have to specify the content id / message id, like cid:, instead of http:. This is described in RFC 2111.

The following example was posted to the JavaMail mailing list from lys to demonstrate using the cid:

import java.io.*;
import java.util.Properties;
import java.util.Date;
import javax.mail.*;
import javax.activation.*;
import javax.mail.internet.*;

public class sendhtml {

  public static void main(String[] argv) {
    new sendhtml(argv);

  public sendhtml(String[] argv) {

    String  to, subject = null, from = null,
      cc = null, bcc = null, url = null;
    String mailhost = null;
    String mailer = "sendhtml";
    String protocol = null, host = null, user = null, password = null;
    String record = null;   // name of folder in which to record mail
    boolean debug = false;
    BufferedReader in =
      new BufferedReader(new InputStreamReader(System.in));
    int optind;

    for (optind = 0; optind < argv.length; optind++) {
      if (argv[optind].equals("-T")) {
        protocol = argv[++optind];
      } else if (argv[optind].equals("-H")) {
        host = argv[++optind];
      } else if (argv[optind].equals("-U")) {
        user = argv[++optind];
      } else if (argv[optind].equals("-P")) {
        password = argv[++optind];
      } else if (argv[optind].equals("-M")) {
        mailhost = argv[++optind];
      } else if (argv[optind].equals("-f")) {
        record = argv[++optind];
      } else if (argv[optind].equals("-s")) {
        subject = argv[++optind];
      } else if (argv[optind].equals("-o")) { // originator
        from = argv[++optind];
      } else if (argv[optind].equals("-c")) {
        cc = argv[++optind];
      } else if (argv[optind].equals("-b")) {
        bcc = argv[++optind];
      } else if (argv[optind].equals("-L")) {
        url = argv[++optind];
      } else if (argv[optind].equals("-d")) {
        debug = true;
      } else if (argv[optind].equals("--")) {
      } else if (argv[optind].startsWith("-")) {
        System.out.println("Usage: sendhtml [[-L 
          store-url] | [-T prot] [-H host] [-U 
          user] [-P passwd]]");
        System.out.println("	[-s subject] [-o 
          from-address] [-c cc-addresses] [-b 
        System.out.println("	[-f record-mailbox] 
          [-M transport-host] [-d] [address]");
      } else {

    try {
      if (optind < argv.length) {
        // XXX - concatenate all remaining arguments
        to = argv[optind];
        System.out.println("To: " + to);
      } else {
        System.out.print("To: ");
        to = in.readLine();
      if (subject == null) {
        System.out.print("Subject: ");
        subject = in.readLine();
      } else {
        System.out.println("Subject: " + subject);

      Properties props = System.getProperties();
      //  could use Session.getTransport() and Transport.connect()
      //  assume we're using SMTP
      if (mailhost != null)
        props.put("mail.smtp.host", mailhost);

      // Get a Session object
      Session session = Session.getDefaultInstance(props, null);
      if (debug)

      // construct the message
      Message msg = new MimeMessage(session);
      if (from != null)
        msg.setFrom(new InternetAddress(from));

        InternetAddress.parse(to, false));
      if (cc != null)
          InternetAddress.parse(cc, false));
      if (bcc != null)
          InternetAddress.parse(bcc, false));


      MimeMultipart mp = new MimeMultipart();


      MimeBodyPart mbp1= new MimeBodyPart();
      String html = 
        "<b> see the following jpg : it is a car!</b><br>"+
        "<a href=a.jsp>hello</a><br>"+
        "<IMG SRC=cid:23abc@pc27 width=80% height=60%><br>"+
        "<b> end of jpg</b>"+


      MimeBodyPart mbp2 = new MimeBodyPart();
      FileDataSource fds = new FileDataSource(
      mbp2.setText("This is a beautiful car !");
      mbp2.setDataHandler(new DataHandler(fds));


      msg.setSentDate(new Date());

Mail was sent successfully.");

    } catch (Exception e) {
You can run it by following steps:
  1. replace the .gif file with another one on your local machine.
  2. javac sendhtml.java
  3. java sendhtml -M test@yahoo.com .
    * is the SMTP Server