JavaMailを使って添付ファイル付きメールの送受信をおこなう

Java

JavaMailを使ってメールの送信や受信をおこなうことができますが、添付ファイル付きメールの送信や受信もおこなうことができます。


今回は、添付ファイル付きメールの送受信について、サンプルプログラムを紹介します。
添付ファイルを付けてメールの送信をおこなうサンプルプログラムと、メールを受信して添付ファイルを保存するサンプルプログラムになります。


添付ファイルを意識していないサンプルプログラムについては、以前に作成した記事を参照ください。


環境情報


今回は、Yahooメールを使ってメールの送受信をおこなってみます。


  • Java1.8.60
  • POP3:Yahooメール
  • SMTP:Yahooメール

添付ファイル付きメールを受信する


メール受信プログラムは以下になります。
1~4が、添付ファイル保存で重要な部分になります。


import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;

import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.internet.MimeMultipart;

public class MailReceiveAtach {

    public static void main(String[] args){
        System.out.print("start: main\r\n");

        try {
            // メール受信のプロパティ設定
            Properties props = new Properties();
            props.put("mail.pop3.host", "pop.mail.yahoo.co.jp");
            props.put("mail.pop3.port", "110");

            // メール受信フォルダをオープン
            Session session = Session.getDefaultInstance(props);
            Store store = session.getStore("pop3");
            store.connect("address", "password");
            Folder folderInbox = store.getFolder("INBOX");
            folderInbox.open(Folder.READ_ONLY);

            // メッセージ一覧を取得
            Message[] arrayMessages = folderInbox.getMessages();
            for (int lc = 0; lc < arrayMessages.length; lc++) {

                // メッセージの取得
                Message message = arrayMessages[lc];

                // 件名の取得と表示
                String subject = message.getSubject();
                System.out.print("件名:" + subject + "\r\n");

                // 受信日時を表示
                String sentDate = message.getSentDate().toString();
                System.out.print("受信日時:" + sentDate + "\r\n");

                // 本文の取得と表示
                MimeMultipart mltp = 
                     (MimeMultipart)message.getContent();
                BodyPart body1 = mltp.getBodyPart(0);
                System.out.print("本文:" + 
                    body1.getContent().toString() + "\r\n");

                // 1:添付ファイルボディを取得
                BodyPart body2 = mltp.getBodyPart(1);
                String fileName = body2.getFileName();
                System.out.print(
                    "添付ファイル名:" + fileName + "\r\n");

                // 2:添付ファイルのストリームを取得
                InputStream ins = body2.getInputStream();

                // 3:出力ストリームに出力しながらファイルを保存する
                OutputStream outs = 
                    new FileOutputStream("save.txt"); 
                int out;
                while ((out = ins.read()) != -1) {
                    outs.write(out);
                }

                // 4:ストリームをクローズ
                ins.close();
                outs.close();

                // 取得の最大件数は10件
                if (lc &amp;amp;gt;= 10) {
                    break;
                }
                System.out.print("\r\n");
            }
        } catch (Exception e) {
            System.out.print("例外が発生!")
            e.printStackTrace();
        } finally {
        }
        System.out.print("end: main\r\n");
    }
}

「1」で、添付ファイルが保存されているボディパートを取得します。
本サンプルプログラムは決め打ちで「1」と記載しています。

本来であれば、ボディパートの数だけループして、添付ファイルが格納されているボディパートについてのみ、「2」以降の添付ファイル保存処理をおこなうべきです。
添付ファイルが複数存在する場合はこのボディパートが複数存在することになるので、ループで回す必要があるということですね。


「2」で、添付ファイルのインプットストリームを取得して、ファイル保存の準備をおこないます。


「3」で、アウトプットストリームを使用して添付ファイルの保存をおこないます。
添付ファイルのファイル名は「save.txt」です。


「4」でストリームをクローズして終了、です。


添付ファイル付きメールを送信する


メール送信プログラムは以下になります。
添付ファイルを2つ添付しているサンプルプログラムになります。


import java.util.Properties;

import javax.mail.Address;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Transport;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.activation.FileDataSource;
import javax.activation.DataHandler;

public class MailSendMlt {

    public static void main(String[] args){
        System.out.print("start: main\r\n");

        try {
            // メール送信のプロパティ設定
            Properties props = new Properties();
            props.put("mail.smtp.host", "smtp.mail.yahoo.co.jp");
            props.put("mail.smtp.port", "587");
            props.put("mail.smtp.auth", "true");
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.ssl.trust", "*");
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.connectiontimeout", "10000");
            props.put("mail.smtp.timeout", "10000");

            // セッションを作成する
            Session session = Session.getInstance(props,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication 
                        getPasswordAuthentication() {
                        return new PasswordAuthentication(
                            "fromAddress", "password");
                    }
                });

            // メールの送信先はYahooメール。送信元もYahooメール
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(
                "fromAddress", "fromAddress"));
            message.setReplyTo(
                new Address[]{new InternetAddress("toAddress")});
            message.setRecipients(
                Message.RecipientType.TO, 
                InternetAddress.parse("toAddress"));
            message.setSubject("テスト");

            // メッセージ本文
            MimeBodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText("テストメール。");

            // 1:添付ファイル1を添付するボディパートを取得
            MimeBodyPart attachedFilePart1 = new MimeBodyPart();

            // 2:添付ファイル1のデータソースを取得
            FileDataSource fs1 = new FileDataSource("attach1.txt");

            // 3:ボディパート1に添付ファイル1を添付
            attachedFilePart1.setDataHandler(new DataHandler(fs1));
            attachedFilePart1.setFileName(
                MimeUtility.encodeWord(fs1.getName()));

            // 4:添付ファイル2を添付するボディパートを取得
            MimeBodyPart attachedFilePart2 = new MimeBodyPart();

            // 5:添付ファイル2のデータソースを取得
            FileDataSource fs2 = new FileDataSource("attach2.txt");

            // 6:ボディパート2に添付ファイル2を添付
            attachedFilePart2.setDataHandler(new DataHandler(fs2));
            attachedFilePart2.setFileName(
                MimeUtility.encodeWord(fs2.getName()));

            // 7:メールに、本文・添付1・添付2の3つを添付
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(messageBodyPart);
            multipart.addBodyPart(attachedFilePart1);
            multipart.addBodyPart(attachedFilePart2);
            message.setHeader(
                "Content-Transfer-Encoding", "base64");

            // 8:メールを送信する
            message.setContent(multipart);
            Transport.send(message);

        } catch (Exception e) {
            System.out.print("例外が発生!\r\n");
            e.printStackTrace();
        } finally {
        }
        System.out.print("end: main\r\n");
    }
}

「1」~「3」が添付ファイル1の作成処理になります。


「1」で、添付ファイルのボディパートを作成します。


「2」で、添付するファイルのデータソースを作成します。


「3」で、添付ファイルを添付します。


「4」~「6」も「1」~「3」と同じで、添付ファイル2を添付します。


「7」で、本文・添付1・添付2をメッセージ本文に添付してメール自体は完成します。


最後に「8」でメールを送信します。


まとめ


紹介したサンプルプログラムで、添付ファイルのメール送受信が可能です。
参考にしてください。





JavaMailを使ってメール送受信をおこなう方法

Java

今回は、JavaMailを使ってメールの受信、および送信おこなう方法を紹介します。


JavaMailとは、Javaに標準実装されているメール送信APIです。
簡単な実装で、メールの受信と送信をおこなうことができます。

今回は、Yahooメールを使用した実装サンプルを紹介します。


環境情報


環境の情報は以下になります。

今回は、Yahooメールを使ってメールの送受信をおこなってみます。

メールはYahooのフリーアカウントを使用します。

  • Java1.8.60
  • POP3:Yahooメール
  • SMTP:Yahooメール

Yahooメールを受信する


メール受信プログラムは以下になります。
YahooメールのPOP3サーバに接続し、受信ボックスに存在するメールを取得して標準出力をおこなっています。
22行目のIDとパスワードは、自分のYahooメールのIDをパスワードを使用してください。


import java.util.Properties;

import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.Message;

public class MailReceive {

    public static void main(String[] args){
        System.out.print("start: main\r\n");

        try {
            // メール受信のプロパティ設定
            Properties props = new Properties();
            props.put("mail.pop3.host", "pop.mail.yahoo.co.jp");
            props.put("mail.pop3.port", "110");

            // メール受信フォルダをオープン
            Session session = Session.getDefaultInstance(props);
            Store store = session.getStore("pop3");
            store.connect("ID", "PW");
            Folder folderInbox = store.getFolder("INBOX");
            folderInbox.open(Folder.READ_ONLY);

            // メッセージ一覧を取得
            Message[] arrayMessages = folderInbox.getMessages();
            for (int lc = 0; lc < arrayMessages.length; lc++) {

                // メッセージの取得
                Message message = arrayMessages[lc];

                // 件名の取得と表示
                String subject = message.getSubject();
                System.out.print("件名:" + subject + "\r\n");

                // 本文の取得と表示
                String content = message.getContent().toString();
                System.out.print("本文:" + content + "\r\n");

                // 取得の最大件数は10件
                if (lc >= 10) {
                    break;
                }
                System.out.print("\r\n");
            }
        } catch (Exception e) {
            System.out.print("例外が発生!");
            e.printStackTrace();
        } finally {
        }
        System.out.print("end: main\r\n");
    }
}

Javaメールのメール受信をおこなえるようにするためには、Yahooメールでの設定変更が必要です。
Yahooメールの設定画面で、POPサーバについて、Yahoo公式サービス以外からのアクセスを許可します。
送信の場合はSMTPを使うので、POPとSMTPについては許可設定をしておく必要があります。


Yahooメール設定1
Yahooメール設定2

Yahooメールを送信する


次にメール送信です。
メールの送信元がYahooメールで、メールの送信先もYahooメールにしています。
自分自身にメールを送っています。


IDとパスワード、メールアドレスについては、実際に送信する情報にあわせて修正が必要になります。


import java.util.Properties;

import javax.mail.Address;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Transport;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class MailSend {

    public static void main(String[] args){
        System.out.print("start: main\r\n");

        try {
            // メール送信のプロパティ設定
            Properties props = new Properties();
            props.put("mail.smtp.host", "smtp.mail.yahoo.co.jp");
            props.put("mail.smtp.port", "587");
            props.put("mail.smtp.auth", "true");
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.ssl.trust", "*");
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.connectiontimeout", "10000");
            props.put("mail.smtp.timeout", "10000");

            // セッションを作成する
            Session session = Session.getInstance(props,
                new javax.mail.Authenticator() {
                    protected 
                        PasswordAuthentication 
                        getPasswordAuthentication() {
                        return new 
                            PasswordAuthentication("ID", "PW");
                    }
                });

            // メールの送信先はYahooメール。送信元もYahooメール
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(
                "fromAddress", "fromName"));
            message.setReplyTo(new Address[]{
                new InternetAddress("toAddress")});
            message.setRecipients(Message.RecipientType.TO, 
                InternetAddress.parse("toAddress"));
            message.setSubject("テスト");
            MimeBodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText("テストメール。");

            // メールのメタ情報を作成
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(messageBodyPart);
            message.setHeader(
                "Content-Transfer-Encoding", "base64");

            // メールを送信する
            message.setContent(multipart);
            Transport.send(message);

        } catch (Exception e) {
            System.out.print("例外が発生!\r\n");
            e.printStackTrace();
        } finally {
        }
        System.out.print("end: main\r\n");
    }
}

筆者がちょっとはまったのが、以下の例外が発生した場合です。


javax.mail.NoSuchProviderException: No provider for smtp
        at javax.mail.Session.getProvider(Session.java:464)
        at javax.mail.Session.getTransport(Session.java:659)
        at javax.mail.Session.getTransport(Session.java:640)
        at javax.mail.Session.getTransport(Session.java:697)
        at javax.mail.Transport.send0(Transport.java:192)
        at javax.mail.Transport.send(Transport.java:124)
        at MailSend.main(MailSend.java:55)

“smtpのプロバイダーが存在しないよ”、と言われてしまっています。


この例外が発生する場合は、実行時のクラスパスに「mail.jar」が含まれていないときです。
「mail.jar」がない状態でビルドしてもビルドエラーにならないので、気が付きにくいかもしれません。


最後に


いかがでしたでしょうか?
Javaメールを使った、メール受信とメール送信の方法について紹介しました。


今回はYahooメールを使用したメール送受信方法を紹介しましたが、他メールサービスでも試してみたいと思います。(いつか。。。)
それではまた!