JavaMailで分割メールを結合するコード

2018年8月4日

JavaMailを使っている時に分割メールを処理しなくちゃいけなくなっちゃったので、とりあえず受信・結合できるようなサンプルコードを書きました。

最近は会社でしかたなくThunderbird(メールソフト)を使っているのですが、OutlookExpress等から送られてくる分割メールに対応していないんですね・・・

結合するファイルはすべてのファイルそろわないといけないので、まずはとりあえず一旦保存しておき、全部そろったら読み込みます。

MimeMessageオブジェクトを読み込めればいいので、POPに残したままでもコードは書けるはずですけど、例外処理とか大変そうです。

MimeMessage mes = null;
FileInputStream filein = null;
filein = new FileInputStream(mailFile);
mes = new MimeMessage( Session.getDefaultInstance(new Properties()) , filein );

分割数・分割番号などは、Content-Type文字列から勝手にContentTypeオブジェクトがとってきてくれます。

私が扱った分割メールは、Content-Type「number(分割番号)」「total(全番号)」「id」の3属性が付いていたのでこれを使います。

String contentType = mes.getContentType();
ContentType c = new ContentType(contentType);
String number= c.getParameter("number");
String total= c.getParameter("total");
String id= c.getParameter("id");

ここで得られた「分割番号・全番号」を元に、結合に必要なファイルをそろえておきます。

分割されたファイルをByteArrayOutputStreamで結合していきます。

分割されたメールオブジェクト(MimeMessage)から、getContent()で ByteArrayInputStream が取得できます。

これを適当な ByteArrayOutputStream baos に順次注入して結合しています。(なので、結合順序を間違えると駄目です)

ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int i=0; i<m.length; i++ ) {
ByteArrayInputStream in = (ByteArrayInputStream)m[i].getContent();
MimeBodyPart p = new MimeBodyPart(in);
p.writeTo(baos);
}

これで、ByteArrayOutputStream fos にすべて結合されましたので、ファイルに出力するなりして確認してみると良いでしょう。

FileOutputStream fos = new FileOutputStream("C:\\temp\\test.eml");
fos.write( baos.toByteArray() );

あーうー メンドクサー