JavaMailでのメール送信まとめその1

Javaでのメール送信まとめ その1。
JavaMailでメール送信。

PCにメール送信

テキストメール

PCにテキストのみのメールを送るサンプル。
MimeMessageの基本的な使い方も。

text/plain
  • MimeMessage作成サンプル(テキストメール)
Properties props = new Properties();
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);

msg.setSubject("PC向けメール送信", "shift-jis");
msg.setFrom(new InternetAddress("from@excample.com"));
msg.setSender(new InternetAddress("sender@example.com"));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress("to@excample.com"));
msg.setText("メールの本文を記述", "shift-jis", "plain");

msg.writeTo(System.out);  // メール内容表示
  • メール内容
From: from@excample.com
Sender: sender@example.com
To: to@excample.com
Message-ID: <19184575.01301990734937.JavaMail.hoge@hoge>
Subject: =?shift-jis?B?UEOM/IKvg4GBW4OLkZeQTQ==?=
MIME-Version: 1.0
Content-Type: text/plain; charset=shift-jis
Content-Transfer-Encoding: base64

g4GBW4OLgsyWe5W2gvCLTI9x
setSubject サブジェクトの設定
setFrom Fromアドレスの設定
setSender Senderアドレスの設定
setRecipient 宛先の設定。RecipientType.TO, RecipientType.CC, RecipientType.BCCを指定。複数のあて先を指定する場合は、setRecipients
setText テキストメール本文設定。文字コード(charset)と、テキストタイプ(subtype:plain,html)を指定する。

MimeMessage#setSubjectでsubjectとcharsetを指定してサブジェクトを指定できます。指定したcharsetに応じて文字コードを変換し、適切なエンコードを行います。

# shift-jis base64
Subject: =?shift-jis?B?UEOM/IKvSFRNTIOBgVuDiyiJ5pGclrOCtSmRl5BN?=
# euc-jp base64
Subject: =?euc-jp?B?UEO4/qSxpeGhvKXrwfe/rg==?=
# utf-8 base64
Subject: =?utf-8?B?UEPlkJHjgZHjg6Hjg7zjg6vpgIHkv6E=?=
  • メールのあて先について

MimeMessage#setRecipientsでは以下のようにメールのあて先を複数指定できます。

msg.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("to1@excample.com"), new InternetAddress("to2@excample.com")});
// To: to1@excample.com, to2@excample.com

また、以下のようにすると、あて先名や、文字コードを指定できます。エンコード(B,Q)はあて先名に応じて適切なものが使用されます。

msg.setRecipient(Message.RecipientType.TO, new InternetAddress("to@excample.com", "いぐざんぷるさん", "shift-jis"));
// To: =?shift-jis?B?gqKCroK0gvGC1YLpgrOC8Q==?= <to@excample.com>
  • メール本文の設定について

MimeMessage#setTextでcharsetとsubtypeを指定して本文を指定できます。ここで指定したcharsetとsubtypeでContent-Typeが作成されますが、本文の文字コードは変換されません。また、subtypeにhtmlを指定すれば、HTMLメールとして送信できます。(代替テキストの無い場合)
setText以外で文字列を設定する場合は、以下のようにsetContentを使用することができます。

msg.setContent("<HTML><BODY>メールの本文を記述</BODY></HTML>", "text/html; charset=shift-jis")
msg.setHeader("Content-Transfer-Encoding", "base64");
  • Content-Transfer-Encoding

setTextで指定したテキストメール本文は最適なエンコードが適用されますが、エンコード(7bit,quated-printable,base64)を指定したい場合はsetTextの後に指定する必要があります。

msg.setText("メールの本文を記述", "shift-jis", "plain");
msg.setHeader("Content-Transfer-Encoding", "base64");    // setTextの後に指定する必要があります。
  • Content-Type

setHeaderでContent-Typeを指定できますが、テキストは変換されません。以下のような場合、テキストの文字コードはshift-jisのままとなります。

msg.setText("メールの本文を記述", "shift-jis", "plain");
msg.setHeader("Content-Type","text/plain; charset=euc-jp");    // euc-jpに変換されないので注意。
  • メッセージIDについて

メッセージIDを変更したい場合は、メッセージIDを生成するメソッドをオーバーライドします。
setHeaderなどで設定する事はできないみたいです。

class MyMimeMessage extends MimeMessage {
    public MyMimeMessage(Session session) {
        super(session);
    }

    @Override
    protected void updateMessageID() throws MessagingException {
        // 元のソース
        //setHeader("Message-ID", "<" + UniqueValue.getUniqueMessageIDValue(session) + ">");
        setHeader("Message-ID", "<hoge.fuga>");
    }
}

// 使うとき
//MimeMessage msg = new MyMimeMessage(session);
HTMLメール
multipart/alternative
 ├ text/plain
 └ text/html
  • MimeMessage作成サンプル(HTMLメール)
Properties props = new Properties();
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);

msg.setSubject("PC向けHTMLメール(画像無し)送信", "shift-jis");
msg.setFrom(new InternetAddress("from@excample.com"));
msg.setSender(new InternetAddress("sender@example.com"));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress("to@excample.com"));

Multipart alternativePart = new MimeMultipart("alternative");

// text mail
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText("メールの本文を記述", "shift-jis", "plain");
textBodyPart.setHeader("Content-Transfer-Encoding", "base64");
alternativePart.addBodyPart(textBodyPart);	// alter

// html mail
MimeBodyPart htmlBodyPart = new MimeBodyPart();
htmlBodyPart.setText("<HTML><BODY>メールの本文を記述</BODY></HTML>", "shift-jis", "html");
htmlBodyPart.setHeader("Content-Transfer-Encoding", "base64");
alternativePart.addBodyPart(htmlBodyPart);

// set alternative
msg.setContent(alternativePart);

msg.writeTo(System.out);  // メール内容表示
  • メール内容
From: from@excample.com
Sender: sender@example.com
To: to@excample.com
Message-ID: <9047389.11301992546179.JavaMail.hoge@hoge>
Subject: =?shift-jis?B?UEOM/IKvSFRNTIOBgVuDiyiJ5pGclrOCtSmRl5BN?=
MIME-Version: 1.0
Content-Type: multipart/alternative; 
        boundary="----=_Part_0_747212.1301992546179"

------=_Part_0_747212.1301992546179
Content-Type: text/plain; charset=shift-jis
Content-Transfer-Encoding: base64

g4GBW4OLgsyWe5W2gvCLTI9x
------=_Part_0_747212.1301992546179
Content-Type: text/html; charset=shift-jis
Content-Transfer-Encoding: base64

PEhUTUw+PEJPRFk+g4GBW4OLgsyWe5W2gvCLTI9xPC9CT0RZPjwvSFRNTD4=
------=_Part_0_747212.1301992546179--


MultipartとMimeBodyPartで以下のようなMIME構造を作成するイメージです。

MimeMessage
└Multipart           // alternative
   ├ MimeBodyPart    // text/plain
   └ MimeBodyPart    // text/html
HTMLメール(インライン画像あり)
multipart/alternative
├ text/plain
└ multipart/related
  ├ text/html
  └ image
  • MimeMessage作成サンプル(HTMLメール)
Properties props = new Properties();
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);

msg.setSubject("PC向けHTMLメール(画像無し)送信", "shift-jis");
msg.setFrom(new InternetAddress("from@excample.com"));
msg.setSender(new InternetAddress("sender@example.com"));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress("to@excample.com"));

Multipart alternativePart = new MimeMultipart("alternative");

// text mail
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText("メールの本文を記述", "shift-jis", "plain");
textBodyPart.setHeader("Content-Transfer-Encoding", "base64");
alternativePart.addBodyPart(textBodyPart);	// alter

// related
MimeBodyPart relatedBodyPart = new MimeBodyPart();
Multipart relatedPart = new MimeMultipart("related");
relatedBodyPart.setContent(relatedPart);
alternativePart.addBodyPart(relatedBodyPart);

// html mail
MimeBodyPart htmlBodyPart = new MimeBodyPart();
htmlBodyPart.setText("<HTML><BODY>メールの本文を記述<IMG src=\"cid:12345@12345\"></BODY></HTML>", "shift-jis", "html");
htmlBodyPart.setHeader("Content-Transfer-Encoding", "base64");
relatedPart.addBodyPart(htmlBodyPart);

// inline image
MimeBodyPart imageBodyPart = new MimeBodyPart();
DataSource dataSource = new FileDataSource("c:/tmp/sample.gif");
DataHandler dataHandler=new DataHandler(dataSource);
imageBodyPart.setDataHandler(dataHandler);
imageBodyPart.setFileName(MimeUtility.encodeWord("sample.gif"));
imageBodyPart.setDisposition("inline");	    // inline指定しておく
imageBodyPart.setContentID("12345@12345");  // インライン画像を指定
relatedPart.addBodyPart(imageBodyPart);

// set alternative
msg.setContent(alternativePart);
  • メール内容
From: from@excample.com
Sender: sender@example.com
To: to@excample.com
Message-ID: <17517359.21301993704968.JavaMail.hoge@hoge>
Subject: =?shift-jis?B?UEOM/IKvSFRNTIOBgVuDiyiJ5pGclrOCtSmRl5BN?=
MIME-Version: 1.0
Content-Type: multipart/alternative; 
        boundary="----=_Part_1_26094370.1301993704952"

------=_Part_1_26094370.1301993704952
Content-Type: text/plain; charset=shift-jis
Content-Transfer-Encoding: base64

g4GBW4OLgsyWe5W2gvCLTI9x
------=_Part_1_26094370.1301993704952
Content-Type: multipart/related; 
        boundary="----=_Part_2_11650554.1301993704952"

------=_Part_2_11650554.1301993704952
Content-Type: text/html; charset=shift-jis
Content-Transfer-Encoding: base64

PEhUTUw+PEJPRFk+g4GBW4OLgsyWe5W2gvCLTI9xPElNRyBzcmM9ImNpZDoxMjM0NUAxMjM0NSI+
PC9CT0RZPjwvSFRNTD4=
------=_Part_2_11650554.1301993704952
Content-Type: image/gif; name=sample.gif
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename=sample.gif

R0lGODlhPAA8AJEAAP9nAf9mAP///wAAACH5BAAAAAAALAAAAAA8ADwAAAL/RI6py+0Po5w0iIuz
3rz7LyTgSJabaKYqh66u2r7yGM82i9w6fsCW1sMwVjXaLxMMNXzJUg55bCqZR6c0ea2SiqAYVis1
hrvPyxeoFafJU3MUvP5w5ZazG0313dv8vWnuEST4hpcC2HFmJxQXWGa1yJeVZ1jVIkk5Rgel6GeV
2YhGCDX5BycKicmImPY1lKpX6KZA5Lizc2jrgptLynuz6+vJ+hPW6riwiBw6LLspO6ukvLR8Qtz0
dG092rdabD04uJ3d2c0c7TreF07mfSeyvpf5mWze866NKq/6XB2Pn65PTb8266aB+wZtU71/CFEc
fFYkIkN/4irho9OOG0GLTJ3gNcoIkqO6ix8XDgQoch6/QiErumRnkmXKmQJlnpwpzZXCmzxRnTMm
UWUwYUN/1SpKSyhSjPuWMnX6AhjUakqnLquANavWrVwZFAAAOw==
------=_Part_2_11650554.1301993704952--

------=_Part_1_26094370.1301993704952--


MultipartとMimeBodyPartで以下のようなMIME構造を作成するイメージです。

MimeMessage
└Multipart               // alternative
   ├ MimeBodyPart        // text/plain
   └ MimeBodyPart        //
     └ Multipart         // related
       ├ MimeBodyPart    // text/html
       └ MimeBodyPart    // inline image
  • 添付ファイル

DataSource、DataHandler、MimeBodyPartで設定します。

  • Content-Disposition

attach(添付)とinline(インライン表示)の指定ができます。

  • Content-ID

HTMLメールで画像は以下のようにContent-IDを指定します。
ここで指定するContent-IDは、仕様上では全てのメールでユニークにする必要があります。(が、メールの中でユニークなら問題なく動作します)
JavaMailでインライン画像を使用する場合は、自分でcidを生成し、HTMLメール内のインライン画像のcidを書き換える対処が必要なので、すこし面倒です。

<IMG src="cid:12345@12345">
テキストメール(添付ファイルあり)
multipart/mixed
├ text/plain
└ attachment
  • MimeMessage作成サンプル
Properties props = new Properties();
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);

msg.setSubject("PC向けテキストメール(添付あり)送信", "shift-jis");
msg.setFrom(new InternetAddress("from@excample.com"));
msg.setSender(new InternetAddress("sender@example.com"));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress("to@excample.com"));

Multipart mixedPart = new MimeMultipart("mixed");

// text mail
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText("メールの本文を記述", "shift-jis", "plain");
textBodyPart.setHeader("Content-Transfer-Encoding", "base64");
mixedPart.addBodyPart(textBodyPart);	// alter

// attach image
MimeBodyPart imageBodyPart = new MimeBodyPart();
DataSource dataSource = new FileDataSource("c:/tmp/sample.gif");
DataHandler dataHandler=new DataHandler(dataSource);
imageBodyPart.setDataHandler(dataHandler);
imageBodyPart.setFileName(MimeUtility.encodeWord("sample.gif"));
imageBodyPart.setDisposition("attachment ");  // attachment 指定しておく
mixedPart.addBodyPart(imageBodyPart);

// set mixed
msg.setContent(mixedPart);
  • メール内容
From: from@excample.com
Sender: sender@example.com
To: to@excample.com
Message-ID: <23910357.31301996950713.JavaMail.hoge@hoge>
Subject: =?shift-jis?B?UEOM/IKvg2WDTINYg2eDgYFbg4sok1mVdIKggugpkZeQTQ==?=
MIME-Version: 1.0
Content-Type: multipart/mixed; 
        boundary="----=_Part_3_25853693.1301996950697"

------=_Part_3_25853693.1301996950697
Content-Type: text/plain; charset=shift-jis
Content-Transfer-Encoding: base64

g4GBW4OLgsyWe5W2gvCLTI9x
------=_Part_3_25853693.1301996950697
Content-Type: image/gif; name=sample.gif
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=sample.gif

R0lGODlhPAA8AJEAAP9nAf9mAP///wAAACH5BAAAAAAALAAAAAA8ADwAAAL/RI6py+0Po5w0iIuz
3rz7LyTgSJabaKYqh66u2r7yGM82i9w6fsCW1sMwVjXaLxMMNXzJUg55bCqZR6c0ea2SiqAYVis1
hrvPyxeoFafJU3MUvP5w5ZazG0313dv8vWnuEST4hpcC2HFmJxQXWGa1yJeVZ1jVIkk5Rgel6GeV
2YhGCDX5BycKicmImPY1lKpX6KZA5Lizc2jrgptLynuz6+vJ+hPW6riwiBw6LLspO6ukvLR8Qtz0
dG092rdabD04uJ3d2c0c7TreF07mfSeyvpf5mWze866NKq/6XB2Pn65PTb8266aB+wZtU71/CFEc
fFYkIkN/4irho9OOG0GLTJ3gNcoIkqO6ix8XDgQoch6/QiErumRnkmXKmQJlnpwpzZXCmzxRnTMm
UWUwYUN/1SpKSyhSjPuWMnX6AhjUakqnLquANavWrVwZFAAAOw==
------=_Part_3_25853693.1301996950697--


MultipartとMimeBodyPartで以下のようなMIME構造を作成するイメージです。

MimeMessage
└Multipart               // mixed
   ├ MimeBodyPart        // text/plain
   └ MimeBodyPart        // attachment file
HTMLメール(添付ファイル、インライン画像あり)
multipart/mixed
├ mulpart/alternative
│ ├ text/plain
│ └ multipart/related
│    ├ text/html
│    └ image (インライン画像)
│
└ image (添付画像)
  • MimeMessage作成サンプル(HTMLメール)
Properties props = new Properties();
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);

msg.setSubject("PC向けHTMLメール(画像無し)送信", "shift-jis");
msg.setFrom(new InternetAddress("from@excample.com"));
msg.setSender(new InternetAddress("sender@example.com"));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress("to@excample.com"));

// mixed
Multipart mixedPart = new MimeMultipart("mixed");

// alternative
MimeBodyPart alternativeBodyPart = new MimeBodyPart();
Multipart alternativePart = new MimeMultipart("alternative");
alternativeBodyPart.setContent(alternativePart);
mixedPart.addBodyPart(alternativeBodyPart);

// text mail
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText("メールの本文を記述", "shift-jis", "plain");
textBodyPart.setHeader("Content-Transfer-Encoding", "base64");
alternativePart.addBodyPart(textBodyPart);	// alter

// related
MimeBodyPart relatedBodyPart = new MimeBodyPart();
Multipart relatedPart = new MimeMultipart("related");
relatedBodyPart.setContent(relatedPart);
alternativePart.addBodyPart(relatedBodyPart);

// html mail
MimeBodyPart htmlBodyPart = new MimeBodyPart();
htmlBodyPart.setText("<HTML><BODY>メールの本文を記述<IMG src=\"cid:12345@12345\"></BODY></HTML>", "shift-jis", "html");
htmlBodyPart.setHeader("Content-Transfer-Encoding", "base64");
relatedPart.addBodyPart(htmlBodyPart);

// inline image
MimeBodyPart imageBodyPart = new MimeBodyPart();
DataSource dataSource1 = new FileDataSource("c:/tmp/sample.gif");
DataHandler dataHandler1 = new DataHandler(dataSource1);
imageBodyPart.setDataHandler(dataHandler1);
imageBodyPart.setFileName(MimeUtility.encodeWord("sample.gif"));
imageBodyPart.setDisposition("inline");	    // inline指定しておく
imageBodyPart.setContentID("12345@12345");  // インライン画像を指定
relatedPart.addBodyPart(imageBodyPart);

// attach image
MimeBodyPart attachBodyPart = new MimeBodyPart();
DataSource dataSource2 = new FileDataSource("c:/tmp/sample.gif");
DataHandler dataHandler2 = new DataHandler(dataSource2);
attachBodyPart.setDataHandler(dataHandler2);
attachBodyPart.setFileName(MimeUtility.encodeWord("sample.gif"));
attachBodyPart.setDisposition("attachment");  // attachment 指定しておく
mixedPart.addBodyPart(attachBodyPart);

// set misedPart
msg.setContent(mixedPart);
  • メール内容
From: from@excample.com
Sender: sender@example.com
To: to@excample.com
Message-ID: <14651377.41301998486594.JavaMail.hoge@hoge>
Subject: =?shift-jis?B?UEOM/IKvSFRNTIOBgVuDiyiJ5pGclrOCtSmRl5BN?=
MIME-Version: 1.0
Content-Type: multipart/mixed; 
        boundary="----=_Part_4_29596205.1301998486594"

------=_Part_4_29596205.1301998486594
Content-Type: multipart/alternative; 
        boundary="----=_Part_5_12528990.1301998486594"

------=_Part_5_12528990.1301998486594
Content-Type: text/plain; charset=shift-jis
Content-Transfer-Encoding: base64

g4GBW4OLgsyWe5W2gvCLTI9x
------=_Part_5_12528990.1301998486594
Content-Type: multipart/related; 
        boundary="----=_Part_6_20688146.1301998486594"

------=_Part_6_20688146.1301998486594
Content-Type: text/html; charset=shift-jis
Content-Transfer-Encoding: base64

PEhUTUw+PEJPRFk+g4GBW4OLgsyWe5W2gvCLTI9xPElNRyBzcmM9ImNpZDoxMjM0NUAxMjM0NSI+
PC9CT0RZPjwvSFRNTD4=
------=_Part_6_20688146.1301998486594
Content-Type: image/gif; name=sample.gif
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename=sample.gif
Content-ID: 12345@12345

R0lGODlhPAA8AJEAAP9nAf9mAP///wAAACH5BAAAAAAALAAAAAA8ADwAAAL/RI6py+0Po5w0iIuz
3rz7LyTgSJabaKYqh66u2r7yGM82i9w6fsCW1sMwVjXaLxMMNXzJUg55bCqZR6c0ea2SiqAYVis1
hrvPyxeoFafJU3MUvP5w5ZazG0313dv8vWnuEST4hpcC2HFmJxQXWGa1yJeVZ1jVIkk5Rgel6GeV
2YhGCDX5BycKicmImPY1lKpX6KZA5Lizc2jrgptLynuz6+vJ+hPW6riwiBw6LLspO6ukvLR8Qtz0
dG092rdabD04uJ3d2c0c7TreF07mfSeyvpf5mWze866NKq/6XB2Pn65PTb8266aB+wZtU71/CFEc
fFYkIkN/4irho9OOG0GLTJ3gNcoIkqO6ix8XDgQoch6/QiErumRnkmXKmQJlnpwpzZXCmzxRnTMm
UWUwYUN/1SpKSyhSjPuWMnX6AhjUakqnLquANavWrVwZFAAAOw==
------=_Part_6_20688146.1301998486594--

------=_Part_5_12528990.1301998486594--

------=_Part_4_29596205.1301998486594
Content-Type: image/gif; name=sample.gif
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=sample.gif

R0lGODlhPAA8AJEAAP9nAf9mAP///wAAACH5BAAAAAAALAAAAAA8ADwAAAL/RI6py+0Po5w0iIuz
3rz7LyTgSJabaKYqh66u2r7yGM82i9w6fsCW1sMwVjXaLxMMNXzJUg55bCqZR6c0ea2SiqAYVis1
hrvPyxeoFafJU3MUvP5w5ZazG0313dv8vWnuEST4hpcC2HFmJxQXWGa1yJeVZ1jVIkk5Rgel6GeV
2YhGCDX5BycKicmImPY1lKpX6KZA5Lizc2jrgptLynuz6+vJ+hPW6riwiBw6LLspO6ukvLR8Qtz0
dG092rdabD04uJ3d2c0c7TreF07mfSeyvpf5mWze866NKq/6XB2Pn65PTb8266aB+wZtU71/CFEc
fFYkIkN/4irho9OOG0GLTJ3gNcoIkqO6ix8XDgQoch6/QiErumRnkmXKmQJlnpwpzZXCmzxRnTMm
UWUwYUN/1SpKSyhSjPuWMnX6AhjUakqnLquANavWrVwZFAAAOw==
------=_Part_4_29596205.1301998486594--


MultipartとMimeBodyPartで以下のようなMIME構造を作成するイメージです。

MimeMessage
└Multipart                   // mixed
  ├ MimeBodyPart             //
  |  └ Multipart            // alternative
  |     ├ MimeBodyPart      // text/plain
  |     └ MimeBodyPart      //
  |       └ Multipart       // related
  |         ├ MimeBodyPart  // text/html
  |         └ MimeBodyPart  // inline image
  └ MimeBodyPart             // attachment file


他のパターンについては、ここまでのコードを参考にしてください。