カテゴリー: JAVA MAIL
JAVA MAILを使用して、IMAP POP3からメールを取得するクラスです
ここ2年ばかりPHPをやってきたのだけど、JAVAがやっぱりいいということで、JAVAをやるはめになりました。
ブログのタイトルは「PHP開発」ですが、昔に戻って、当分JAVAをやりそうです。
よろしく!
そんなことで、Java Mailを使ってメールボックスからメールを取得するクラスを作ってみました。
ご意見ご感想をお待ちしています。
package jp.compsys.common.util;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Address;
import javax.mail.Message.RecipientType;
import javax.mail.internet.MimeUtility;
import com.sun.mail.util.QPDecoderStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Properties;
import java.util.ArrayList;
/**
* サーバからメールを取得するクラス.
*
* @author Computer System Corp tamura
* @since 1.6
* @version 1.0
* @since 1.0
*/
public class MailReader implements Serializable
{
private static final long serialVersionUID = -8161055025994457665L;
private String server;
private String protocol = "imap";
private int port = 143;
private String userId;
private String password;
private int pageNo = 0;
private int recordCount = 0;
private int maxPageNo = 0;
private Session session;
private Store store;
private Folder folder;
/**
* MailReaderのコンストラクタ.
* @param server 接続するサーバ名またはIPアドレス
* @param port 接続するポート番号
* @param userId 接続するユーザID
* @param password 接続するパスワード
* @since 1.6
*/
public MailReader(String server, int port, String userId, String password)
{
this.server = server;
this.protocol="imap";
this.port = port;
this.userId = userId;
this.password = password;
/*
this.protocol="pop3";
this.port = -1;
*/
}
/**
* メールの内容を取得する。.
* @param msgnum メッセージ番号
* @return MailItemのインスタンスを返す。取得できない場合はnullを返す。
*/
public MailItem getMail(int msgnum)
{
MailItem mailItem = new MailItem();
if(!open()) return null;
try
{
folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
if (!folder.exists())
{
close();
return null;
}
Message m = folder.getMessage(msgnum);
messageEdit(m, mailItem);
Part p = m;
partSet(p, mailItem);
} catch (MessagingException ex)
{
mailItem = null;
ex.printStackTrace();
} catch (IOException ex)
{
mailItem = null;
ex.printStackTrace();
}
close();
return mailItem;
}
/**
* メールの一覧を取得(mailList)した後の実際の取得ページ番号を取得する。
* mailListメソッドを実行した後でなければ正しい値を返さない。.
*/
public int getPageNo()
{
return pageNo;
}
/**
* メールの一覧を取得(mailList)した時の総メール数を取得する。
* mailListメソッドを実行した後でなければ正しい値を返さない.
*/
public int getRecordCount()
{
return recordCount;
}
/**
* メールの一覧を取得(mailList)した時の最大ページ数を取得する。
* mailListメソッドを実行した後でなければ正しい値を返さない.
*/
public int getMaxPageNo()
{
return maxPageNo;
}
/**
* メールサーバに接続する。.
* @return true:成功 false:失敗
*/
private boolean open()
{
Properties properties = System.getProperties();
session = Session.getInstance(properties, null);
try
{
store = session.getStore(protocol);
store.connect(server, port, userId, password);
return true;
} catch (MessagingException ex)
{
ex.printStackTrace();
return false;
}
}
/**
* メールサーバとの接続をクローズする
*/
private void close()
{
if (null != store)
{
try
{
store.close();
} catch (MessagingException ex)
{
}
}
}
/**
* メールに含まれるメッセージや添付ファイルを取得する。.
*/
@SuppressWarnings("unchecked")
public void partSet(Part p, MailItem m) throws MessagingException, IOException
{
MailContent mailContent = new MailContent();
String disp = p.getDisposition();
if (p.isMimeType("multipart/*"))
{ // マルチパートの場合
Multipart mp = (Multipart) p.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++)
{
partSet(mp.getBodyPart(i), m);
}
return;
}
else if (p.isMimeType("message/rfc822"))
{ // メッセージの場合
partSet((Part) p.getContent(), m);
return;
}
else if (p.isMimeType("text/*"))
{
if(disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT))
{
mailContent.attachmentFlg = true;
}
mailContent.header = p.getAllHeaders();
mailContent.contentType = p.getContentType();
mailContent.content = content2string(p.getContent());
m.mailContents.add(mailContent);
return;
}
// 添付ファイルの場合
if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT))
{
mailContent.contentBinaryFlg = true;
mailContent.fileName = p.getFileName();
if (mailContent.fileName != null)
{
mailContent.fileName = MimeUtility.decodeText(mailContent.fileName);
}
else
{
mailContent.fileName = "";
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try
{
p.writeTo(os);
mailContent.content_binary = os.toByteArray();
} catch (IOException e)
{
e.printStackTrace();
}
mailContent.header = p.getAllHeaders();
mailContent.contentType = p.getContentType();
mailContent.attachmentFlg=true;
m.mailContents.add(mailContent);
}
}
/**
* text/* に含まれるコンテンツを文字列として受け取る.
* @param textコンテンツの内容
*/
private String content2string(Object obj) throws MessagingException
{
String ret = "";
if (obj instanceof String)
{
return (String) obj;
}
else if (obj instanceof QPDecoderStream)
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
QPDecoderStream qps = (QPDecoderStream) obj;
while (true)
{
try
{
int c = qps.read();
if (c == -1) break;
os.write(c);
} catch (IOException ex)
{
return ret;
}
}
ret = os.toString();
}
else
{
throw new MessagingException("textのコンテンツファイルに未定義のものがあります");
}
return ret;
}
/**
* メールの一覧をぺジ単位に取得します。
* @param lineCount 1ページあたりの行数
* @param pageNo 取得したいページ
* @return 取得したメールの一覧を返します。メールがない場合はnullを返します。
*/
public ArrayList mailList(int lineCount, int pageNo)
{
this.pageNo = pageNo;
recordCount = 0;
maxPageNo = 0;
ArrayList list = null;
open();
int start = 0;
int end = 0;
int cnt = 0;
try
{
folder = store.getFolder("INBOX");
if (!folder.exists())
{
close();
return list;
}
folder.open(Folder.READ_ONLY);
cnt = folder.getMessageCount();
if (0 == cnt)
{
close();
return list;
}
recordCount = cnt;
maxPageNo = (int) Math.ceil((double) cnt / (double) lineCount);
if (this.pageNo maxPageNo) this.pageNo = maxPageNo;
list = new ArrayList(cnt);
Message mes[] = folder.getMessages();
for (Message m : mes)
{
MailItem mailItem = new MailItem();
messageEdit(m, mailItem);
// 一覧にメールの内容も取得したい場合はコメントをはずす かなり遅くなるのでやめたほうがいいです。
/* Part p = m;
partSet(p, mailItem);
*/ list.add(mailItem);
}
folder.close(false);
} catch (MessagingException ex)
{
ex.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
}
close();
Collections.sort(list, new Comparator()
{
public int compare(MailItem o1, MailItem o2)
{
return (o1.sentDate.compareTo(o2.sentDate) * (-1));
}
});
start = (this.pageNo - 1) * lineCount;
if (this.pageNo == maxPageNo)
{
end = start + ((cnt - 1) % lineCount);
}
else
{
end = start + lineCount - 1;
}
int i = -1;
ArrayList retList = new ArrayList(end - start + 1);
for (MailItem m : list)
{
i++;
if (i end) break;
retList.add(m);
}
return retList;
}
/**
* メッセージに含まれるヘダー情報を取得編集する。
* @param m javax.mail.Message
* @param mailItem 編集対象
*/
private void messageEdit(Message m, MailItem mailItem)
{
try
{
mailItem.messageNo = m.getMessageNumber();
mailItem.sentDate = m.getSentDate();
mailItem.receivedDate = m.getReceivedDate();
mailItem.subject = m.getSubject();
Flags flags = m.getFlags();
String[] userFlg = flags.getUserFlags();
{
if (m.isSet(Flags.Flag.ANSWERED))
{
mailItem.systemFlg.add("ANSWERED");
}
if (m.isSet(Flags.Flag.DELETED))
{
mailItem.systemFlg.add("DELETED");
}
if (m.isSet(Flags.Flag.DRAFT))
{
mailItem.systemFlg.add("DRAFT");
}
if (m.isSet(Flags.Flag.FLAGGED))
{
mailItem.systemFlg.add("FLAGGED");
}
if (m.isSet(Flags.Flag.RECENT))
{
mailItem.systemFlg.add("RECENT");
}
if (m.isSet(Flags.Flag.SEEN))
{
mailItem.systemFlg.add("SEEN");
}
if (m.isSet(Flags.Flag.USER))
{
mailItem.systemFlg.add("USER");
}
}
if (null != userFlg)
{
for (int i = 0; i < userFlg.length; i++)
{
mailItem.userFlg.add(userFlg[i]);
}
}
if (null != m.getFrom())
{
for (Address a : m.getFrom())
{
mailItem.from.add(MimeUtility.decodeText(a.toString()));
}
}
if (null != m.getReplyTo())
{
for (Address a : m.getReplyTo())
{
mailItem.replyTo.add(MimeUtility.decodeText(a.toString()));
}
}
if (null != m.getRecipients(RecipientType.TO))
{
for (Address a : m.getRecipients(RecipientType.TO))
{
mailItem.to.add(MimeUtility.decodeText(a.toString()));
}
}
if (null != m.getRecipients(RecipientType.CC))
{
for (Address a : m.getRecipients(RecipientType.CC))
{
mailItem.cc.add(MimeUtility.decodeText(a.toString()));
}
}
if (null != m.getRecipients(RecipientType.BCC))
{
for (Address a : m.getRecipients(RecipientType.BCC))
{
mailItem.bcc.add(MimeUtility.decodeText(a.toString()));
}
}
} catch (UnsupportedEncodingException ex)
{
ex.printStackTrace();
} catch (MessagingException ex)
{
ex.printStackTrace();
} finally
{
}
}
}