java 使用非socket方式获取接收邮件 POP3 通过时间过滤
之前介绍了邮件接收方式是socket方式的,总的来说还比较靠谱。
当前这种方式,我试过邮件比较少得情况下,还是可以正常接收的,如果邮件一多的时候,邮件进行过滤,那么就非常非常慢。。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; import javax.mail.BodyPart; 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.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import javax.mail.search.ComparisonTerm; import javax.mail.search.SentDateTerm; import com.ccjr.commons.util.MyDateUtil; import com.sun.mail.pop3.POP3Folder; import com.sun.mail.pop3.POP3Store; import com.sun.mail.util.MailSSLSocketFactory; import lombok.extern.slf4j.Slf4j; @Slf4j public class ReciveITest { // 邮件 String uid = "用户名"; String pid = "密码"; // 邮箱服务器 String emailhost = "pop.exmail.qq.com"; public static void main(String[] args) throws Exception{ ReciveITest reciveIPopTest = new ReciveITest(); // reciveIPopTest.receiveMail(); reciveIPopTest.receiveMailFilter(); } /**接收pop邮件*/ public void receiveMailFilter() throws Exception { POP3Store store = null; try { Properties properties = new Properties(); properties.setProperty("mail.popStore.protocol", "pop3"); // 使用pop3协议 properties.setProperty("mail.pop3.port", "995"); // 端口 MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); properties.put("mail.pop3.ssl.socketFactory", sf); properties.put("mail.pop3.ssl.enable", true); properties.setProperty("mail.pop3.host", "pop.qq.com"); Session session = Session.getInstance(properties); store = (POP3Store) session.getStore("pop3"); store.connect(emailhost, 995, uid, pid); POP3Folder pop3Folder = (POP3Folder) store.getFolder("INBOX"); pop3Folder.open(Folder.READ_ONLY); // 打开收件箱 // 创建ReceivedDateTerm对象,ComparisonTerm.GE(大于等于),指定时间后的邮件 Date fileDate = MyDateUtil.dateStrToDate(MyDateUtil.DATE_TIME_FMT, "2023-03-19 14:00:00"); log.info("时间:" + MyDateUtil.dateToDateStr(MyDateUtil.DATE_TIME_FMT, fileDate)); SentDateTerm term = new SentDateTerm(ComparisonTerm.GE, fileDate); Message[] messages = pop3Folder.search(term); // FetchProfile fetchProfile = new FetchProfile(); // fetchProfile.add(FetchProfile.Item.ENVELOPE); // FlagTerm flagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false); // Message[] messages = pop3Folder.search(flagTerm); // pop3Folder.fetch(messages, fetchProfile); log.error("收件箱的邮件数:" + messages.length); // Folder folder = pop3Folder.getStore().getDefaultFolder(); // Folder[] folders = folder.list(); // for (int i = 0; i < folders.length; i++) { // log.error("名称:" + folders[i].getName()); // } // 展示邮件内容 this.showMessage(pop3Folder, messages); } catch (Exception e) { log.error("异常:",e); } finally { if (store != null) { store.close(); } } } /**展示邮件内容 * @throws Exception */ public void showMessage(POP3Folder pop3Folder, Message[] messages) throws Exception { for (int i = 0; i < messages.length; i++) { String infomsg = "第" + (i + 1) + "封"; log.info("---------------"+infomsg+"----------------start-----------------"); MimeMessage emailMessage = (MimeMessage) messages[i]; try { String from = MimeUtility.decodeText(emailMessage.getFrom()[0].toString()); InternetAddress ia = new InternetAddress(from); log.info("发件人:" + ia.getPersonal() + '(' + ia.getAddress() + ')'); }catch(Exception e) { e.printStackTrace(); log.info("异常" + e.getMessage()); } // 注意UID与MessageID并非一个东西,UID是邮箱用来标识你这个账户的每一封邮件的东西,而MessageID是发送邮件的时候生成的唯一ID // log.info("发件人:" +msg.getFrom()); log.info("ID:" + pop3Folder.getUID(emailMessage)); log.info("主题:" + emailMessage.getSubject()); log.info("发送时间:" + MyDateUtil.dateToDateStr(MyDateUtil.DATE_TIME_FMT, emailMessage.getSentDate())); log.info("类型:" + emailMessage.getContentType()); // log.info("内容:" + msg.getContent()); boolean isContainerAttachment = isContainAttachment(emailMessage); log.info("是否包含附件:" + isContainerAttachment); // if (isContainerAttachment) { // //设置需要保存的目录并保存附件 // String path = "D:\\upload\\"+MyDateUtil.dateToDateStr(MyDateUtil.DATE_FMT, emailMessage.getSentDate()); // this.saveAttachment(emailMessage, path); //保存附件 // } // 邮件设为已读 // msg.setFlag(Flags.Flag.SEEN, true); log.info("---------------"+infomsg+"----------------end-----------------"); } } /** * 判断邮件中是否包含附件 * * @param * @return 邮件中存在附件返回true,不存在返回false * @throws MessagingException * @throws Exception */ public static boolean isContainAttachment(Part part) throws Exception { boolean flag = false; if (part.isMimeType("multipart/*")) { MimeMultipart multipart = (MimeMultipart) part.getContent(); int partCount = multipart.getCount(); for (int i = 0; i < partCount; i++) { BodyPart bodyPart = multipart.getBodyPart(i); String disp = bodyPart.getDisposition(); if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) { flag = true; } else if (bodyPart.isMimeType("multipart/*")) { flag = isContainAttachment(bodyPart); } else { String contentType = bodyPart.getContentType(); if (contentType.indexOf("application") != -1) { flag = true; } if (contentType.indexOf("name") != -1) { flag = true; } } if (flag) { break; } } } else if (part.isMimeType("message/rfc822")) { flag = isContainAttachment((Part) part.getContent()); } return flag; } /** * 保存附件 * * @param part 邮件中多个组合体中的其中一个组合体 * @param destDir 附件保存目录 * @throws UnsupportedEncodingException * @throws MessagingException * @throws FileNotFoundException * @throws IOException */ public void saveAttachment(Part part, String destDir) throws Exception { if (part.isMimeType("multipart/*")) { Multipart multipart = (Multipart) part.getContent(); // 复杂体邮件 // 复杂体邮件包含多个邮件体 int partCount = multipart.getCount(); for (int i = 0; i < partCount; i++) { // 获得复杂体邮件中其中一个邮件体 BodyPart bodyPart = multipart.getBodyPart(i); // 某一个邮件体也有可能是由多个邮件体组成的复杂体 String disp = bodyPart.getDisposition(); if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) { InputStream is = bodyPart.getInputStream(); saveFile(is, destDir, decodeText(bodyPart.getFileName())); } else if (bodyPart.isMimeType("multipart/*")) { saveAttachment(bodyPart, destDir); } else { String contentType = bodyPart.getContentType(); if (contentType.indexOf("name") != -1 || contentType.indexOf("application") != -1) { saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName())); } } } } else if (part.isMimeType("message/rfc822")) { saveAttachment((Part) part.getContent(), destDir); } } /** * 读取输入流中的数据保存至指定目录 * * @param is 输入流 * @param fileName 文件名 * @param destDir 文件存储目录 * @throws Exception */ private void saveFile(InputStream is, String destDir, String fileName) throws Exception { File file = new File(destDir+File.separator + fileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } // 如果文件名称包含关键字则进行保存 BufferedInputStream bis = new BufferedInputStream(is); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); int len = -1; while ((len = bis.read()) != -1) { bos.write(len); bos.flush(); } bos.close(); bis.close(); } /** * 文本解码 * * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本 * @return 解码后的文本 * @throws UnsupportedEncodingException */ public String decodeText(String encodeText) throws UnsupportedEncodingException { if (encodeText == null || "".equals(encodeText)) { return ""; } else { return MimeUtility.decodeText(encodeText); } } }