ビジネスシーンでは電子メール処理は現役
前回の記事 https://qiita.com/sev01/items/6c8ea0c1a82324341fdd ではメールの送信をしましたが、受信したメールを保存し、そこからデータを抽出することは日常業務の中でよく使われます。
マルチパートって色々あります
マルチパートの中に、さらにマルチパートとなっていることがあります。
つまり、入れ子になっていることがあるため、ある種の再起処理が必要になります。
添付ファイルの名前が文字化けする問題に遭遇
JavaMailのMimeUtility.decodeText を利用します。
例
package mailreceivetest;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.StringJoiner;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Multipart;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
public class MailRecieveTest {
/**
* @param args the command line arguments
* @throws javax.mail.NoSuchProviderException
* @throws java.io.IOException
*/
public static void main(String[] args) throws NoSuchProviderException, MessagingException, IOException {
String host = "XXXXXXXX.jp";
int port = 993;
String user = "<ユーザー名>";
String password = "<パスワード>";
String target_folder = "INBOX";
Properties props = System.getProperties();
Session session = Session.getInstance(props, null);
session.setDebug(false); // trueにするとサーバーとのやりとりが見られます
try ( Store store = session.getStore("imaps")) {
store.connect(host, port, user, password);
Folder inboxFolder = store.getFolder(target_folder);
if (inboxFolder.exists()) {
inboxFolder.open(Folder.READ_ONLY); // Folder.READ_WRITEすると読み書き
for (Message message : inboxFolder.getMessages()) {
String subject = message.getSubject();
System.out.println("タイトル:" + MimeUtility.decodeText(subject));
Object objContent = message.getContent();
if (objContent instanceof Multipart) {
System.out.println("親マルチパート");
MimeMultipart mmp = (MimeMultipart) message.getContent();
int multipartCount = mmp.getCount();
System.out.println("パートの数:" + multipartCount);
for (int i = 0; i < multipartCount; i++) {
System.out.println(saveMultiPart(mmp.getBodyPart(i)));
}
} else {
System.out.println("マルチパートではない");
}
// message.setFlag(Flags.Flag.DELETED, true); // 消去フラグ
}
inboxFolder.close(false); // trueにするとフラグが反映される
} else {
System.out.printf("%s というフォルダーはありません。", target_folder);
}
}
}
/**
* マルチパートのファイルを保存しテキストパートの内容を出力
*
* @param bodyPart
* @return
*/
static String saveMultiPart(BodyPart bodyPart) {
StringJoiner sj = new StringJoiner(System.lineSeparator());
try {
String contentType = bodyPart.getContentType();
System.out.println("ContentType:" + contentType);
if (bodyPart.isMimeType("text/plain")) {
sj.add(bodyPart.getContent().toString());
}
if (bodyPart.isMimeType("text/html")) {
System.out.println("HTMLパートです");
}
if (bodyPart.isMimeType("multipart/alternative")) {
System.out.println("多重マルチパート");
Object objContent = bodyPart.getContent();
if (objContent instanceof Multipart) {
Multipart name = (Multipart) objContent;
int multiPartCount = name.getCount();
for (int i = 0; i < multiPartCount; i++) {
System.out.println("子マルチパート:" + i);
sj.add(saveMultiPart(name.getBodyPart(i)));
}
} else {
System.err.println("マルチパートが抽出できませんでした");
}
}
String fileName = bodyPart.getFileName();
if (fileName != null) {
String jfileName = MimeUtility.decodeText(fileName);
System.out.println("保存します:" + jfileName);
try ( InputStream ins = bodyPart.getInputStream();
OutputStream outs = new BufferedOutputStream(new FileOutputStream(jfileName))) {
int out;
while ((out = ins.read()) != -1) {
outs.write(out);
}
}
}
} catch (IOException | MessagingException ex) {
System.err.println("ERR:" + ex.getMessage());
}
return sj.toString();
}
}