在 JavaMail 中,可以不像上面文章那样子调用 Folder.getMessages() 方法把邮件夹中的所有都返回,而是可以根据给定的一些条件过滤搜索出我们想要的邮件,之后再对进行获得的邮件进行操作。现在的邮箱大多都支持邮件搜索这一功能了。

要使用搜索过滤功能,必须用到 java.mail.search 包中的 SearchTerm 抽象类。在这个包中,我们可以使用其他具有不同组合关系的子类和具有不同搜索条件的类来进行操作。

1、逻辑组合关系的子类有:AndTerm 类、OrTerm 类、NotTerm 类、ComparisonTerm 类,它们都是 SearchTerm 抽象类的具体子类;

2、具体搜索条件的类有:DateTerm 类、BodyTerm 类、HeaderTerm 类,这几个都是抽象类,具体应用时应该由其对应的子类来实现。

看一些 JavaMail 帮助文档中关于 java.mail.search 包中的类集:

SearchMails01

程序要求:

搜索出 testhao@126.com 邮箱中发件人地址为 test_hao@sina.cn ,主题为 “测试1”的邮件,并由用户输入是否设置删除标记,在断开网络连接(即程序运行结束)之后 POP3 服务器会将设置有删除标记的邮件删除掉。而设置删除标记,需要用到 Message.setFlag() 方法。

目前我们往 testhao@126.com 邮箱发送了 6 封邮件,如下图,其中第一封主题为“测试1”的邮件是由 test_hao@163.com 发送的,其他的 5 封由 test_hao@sina.cn 所发。

SearchMails02

代码实现: 

  1. import java.io.BufferedReader;  
  2. import java.io.InputStreamReader;  
  3. import java.util.Properties;  
  4.  
  5. import javax.mail.Flags;  
  6. import javax.mail.Folder;  
  7. import javax.mail.Message;  
  8. import javax.mail.Session;  
  9. import javax.mail.Store;  
  10. import javax.mail.search.AndTerm;  
  11. import javax.mail.search.FromStringTerm;  
  12. import javax.mail.search.SearchTerm;  
  13. import javax.mail.search.SubjectTerm;  
  14.  
  15. /**  
  16.  * 使用 java.mail.search 包中的 SearchTerm 类  
  17.  * 在接收邮件时进行组合搜索、过滤  
  18.  * @author haolloyin  
  19.  */ 
  20. public class SearchMails {  
  21.     public static void main(String[] args) throws Exception {  
  22.         // 连接pop3服务器的主机名、协议、用户名、密码  
  23.         String pop3Server = "pop3.126.com";  
  24.         String protocol = "pop3";  
  25.         String user = "testhao";  
  26.         String pwd = "123456";  
  27.           
  28.         // 创建一个有具体连接信息的Properties对象  
  29.         Properties props = new Properties();  
  30.         props.setProperty("mail.store.protocol", protocol);  
  31.         props.setProperty("mail.pop3.host", pop3Server);  
  32.           
  33.         // 使用Properties对象获得Session对象  
  34.         Session session = Session.getInstance(props);  
  35.         session.setDebug(true);  
  36.           
  37.         // 利用Session对象获得Store对象,并连接pop3服务器  
  38.         Store store = session.getStore();  
  39.         store.connect(pop3Server, user, pwd);  
  40.           
  41.         // 获得邮箱内的邮件夹Folder对象,以"读-写"打开  
  42.         Folder folder = store.getFolder("inbox");  
  43.         folder.open(Folder.READ_WRITE);  
  44.           
  45.           
  46.         // 搜索发件人为 test_hao@sina.cn 和主题为"测试1"的邮件  
  47.         SearchTerm st = new AndTerm(  
  48.                 new FromStringTerm("test_hao@sina.cn"),  
  49.                 new SubjectTerm("测试1"));  
  50.           
  51. //      // 获得邮件夹Folder内的所有邮件Message对象  
  52. //      Message [] messages = folder.getMessages();  
  53.           
  54.         // 不是像上面那样直接返回所有邮件,而是使用Folder.search()方法  
  55.         Message [] messages = folder.search(st);  
  56.         int mailCounts = messages.length;  
  57.         System.out.println("搜索过滤到" + mailCounts + " 封符合条件的邮件!");  
  58.           
  59.         for(int i = 0; i < mailCounts; i++) {  
  60.               
  61.             String subject = messages[i].getSubject();  
  62.             String from = (messages[i].getFrom()[0]).toString();  
  63.               
  64.             System.out.println("第 " + (i+1) + "封邮件的主题:" + subject);  
  65.             System.out.println("第 " + (i+1) + "封邮件的发件人地址:" + from);  
  66.               
  67.             System.out.println("是否删除该邮件(yes/no)?:");  
  68.             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  
  69.             String input = br.readLine();  
  70.             if("yes".equalsIgnoreCase(input)) {  
  71.                 // 直接输出到控制台中  
  72. //              messages[i].writeTo(System.out);  
  73.                 // 设置删除标记,一定要记得调用saveChanges()方法  
  74.                 messages[i].setFlag(Flags.Flag.DELETED, true);  
  75.                 messages[i].saveChanges();  
  76.                 System.out.println("成功设置了删除标记!");  
  77.             }             
  78.         }  
  79.         // 关闭连接时设置了删除标记的邮件才会被真正删除,相当于"QUIT"命令  
  80.         folder.close(false);  
  81.         store.close();  
  82.     }  

运行过程:

SearchMails03

SearchMails04

SearchMails05

糟糕的是,不同 POP3  服务器对于邮件的访问权限的限制是不同的,在这里,pop3.126.com 服务器就不允许修改邮件了。所以,删除失败!!!SearchMails06

 

我的相关文章:

图解使用Telnet程序手工发送邮件

图解使用telnet程序手工接收邮件及其过程

JavaMail:简单的邮件接收程序

组合模式(Composite)的安全模式与透明模式

管道过滤器模式(Pipe and Filter)与组合模式(修改)