现在的位置: 首页 > 综合 > 正文

javaMail 接收邮件

2013年10月04日 ⁄ 综合 ⁄ 共 15809字 ⁄ 字号 评论关闭

source:http://www.blogjava.net/fengliangjun/archive/2006/06/03/5740.html

可以用

import java.util.Properties;

import javax.mail.*;
import javax.mail.internet.*;

public class receivemail {
 public static void main(String[] args) throws Exception {

  Properties props = new Properties();
  Session recesession = Session.getDefaultInstance(props, null);
  recesession.setDebug(true);

  Store store = recesession.getStore("pop3");
  String user = "****";//帐户
  String password = "*****";//密码
  store.connect("pop.163.com", user, password);

  Folder folder = store.getFolder("INBOX");
  
  folder.open(Folder.READ_ONLY);
  
  Message[] msgs = folder.getMessages();
  for (int msgNum = 0; msgNum < msgs.length; msgNum++) {
   
   System.out.println(msgs[msgNum].getSentDate());
   System.out.println(msgs[msgNum].getSubject());
   System.out.println(msgs[msgNum].getContent());
  }
  folder.close(false);
  store.close();

 }

}

百度文库:

怎么用JavaMail收取邮件
本文由nix1001贡献
doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。
怎么用 JavaMail 收取邮件
从一个应用程式发送邮件是非常容易的操作,然而你肯定希望从服务器收取邮件也这样简单. 从一个应用程式发送邮件是非常容易的操作,然而你肯定希望从服务器收取邮件也这样简单.这里将为你 收取邮件的过程. 演示使用 JavaMail 收取邮件的过程. 以前,我们介绍过使用 JavaMail 和 Apache Commons Email 发送邮件的方法.其中,Commons Email 没有包含收取邮件功能,只是集中在发送邮件功能上.对于邮件的收取,我们必须使用到 JavaMail 功能. 发送邮件只需要协议(SMTP),
其过程相对比较简单. 而接收邮件则包含两个协议, POP3 和 IMAP. 即 POP3 是老协议,他提供一个单一收信箱,以存放一定顺序的邮件信息.IMAP 相对比较新,他为邮件提供连接 到一个层次关系的文件入口,其中一个入口即为收信箱.当然更有其他能使用的协议,POP3 和 IMAP 只 是其中一种安全性非常好的协议.JavaMail 将这些协议提炼为一种邮件仓库(Store)的概念,这一仓库为文 件等级的集合.这种提炼意味着仓库包含非常多内容,但我们只需要弄清晰在一个服务目录中浏览和导航 邮件信息的过程,而实际处理邮件协议的任务则通过
JavaMail 调用 Provider 来完成. JavaMail 的 Provider 操作服务于 POP3 和 IMAP,这就确保了 POP3S 和 IMAPS 的安全性.值得提醒的 是,你能将另外的 Providers 嵌入到 JavaMail API 以处理其他诸如 NNTP 或本地存储邮件的协议.在 Sun 主页上列出这方面的第三方 Providers. 让我们看看一个实际的例子:MailPage.我们的任务是建立一个最新发送邮件的网页,该页面允许远程用 户无需直接访问 web 服务器的情况下更新邮件,而这一过程只需要通过发送一个邮件到一个特定的邮件帐
号. 实现这一过程的关键是使用 MailRetriever.在操作之前需要 4 种数据:邮件用户帐号名称,帐号密码,服 务器的主机名, Provider 名称. 及 "pop3", "pop3s", "map", "maps"就是标准的数据. 目前我们能用 getMail 方法获得邮件.首先我们需要一个 Session 来发送邮件.我们获得一个 Session: Properties props=System.getProperties(); session=Session.getInstance(props,null);
从这一 Session,我们能得到适合于 provider 的一个 Store: store=session.getStore(emailprovider); 使用服务器名称,用户名及密码,通过调用 Store 的 connect 方法来连接到 Session: store.connect(emailserver,emailuser,emailpassword); 目前,我们能浏览 Folder 的层次.为了得到层次的顶部,我们需求查看一个默认的 Folder. folder=store.getDefaultFolder();
每一 Folder 能包含非常多其他的目录.例如,能通过 getFolder 方法浏览收信箱. inboxfolder=folder.getFolder("INBOX"); 此时,能查看 IMAP 树中的文件.而对于 POP3,他以单一队列将文件映射到一个收信箱.为了操作文件 中的信息,需要打开目录: inboxfolder.open(Folder.READ_ONLY); 我们以 READ_ONLY 模式打开目录, 因为我们不想改动文件的性质和内容. 而使用 READ_WRITE 将会改 动文件.目前,我们能获得目录内的所有一组信息:
Message[] msgs=inboxfolder.getMessages(); 能反复迭代这一过程,但这一方法效率非常低.我们采用的方法是指定 API,以得到信息标题感兴趣的部 分,由此能获得这些信息的标题.输入 FetchProfile 类,这一类允许指定一个 API: FetchProfile fp=new FetchProfile(); fp.add("Subject");
我们只对 Subject 的标题感兴趣,所以将 Subject 标题加入到 FetchProfile.你能使用两个技巧: FetchProfile.Item.ENVELOPE (针对于普通 From, To, CC 等)或 FetchProfile.Item.CONTENT_INFO (针对 于有关信息内容大小和类型的信息).目前我们请求文件在整个域内接收信息: inboxfolder.fetch(msgs,fp); 我们将反复操作整个 Subject 标题.对于 MailPage,以"MailPage"的特定字符串作为查找对象.以数组的
顶部开始查找,直到找到合适的信息: for(int j=msgs.length-1;j>=0;j--) { if(msgs[j].getSubject().startsWith("MailPage:")) { setLatestMessage(msgs[j]);< break; } } 回到 setLatestMessage,目前我们只需要关闭和保持文件: inboxfolder.close(false); store.close(); 根据判断邮件是否已被删除,文件即关闭或保留收件箱.这里我们给出 false(没有被删除),因为我们不想
改动邮件箱的状态. 这样就能完成邮件的收取过程. 目前我们能通过例子中的 setLatestMessage 方法排列邮件. 你所需要注意 的第一件事为邮件的不同格式.邮件的基本格式是纯文本.怎么才能识别这种格式?第一步就是检查信息 的内容类型,可通过"text/plain"识别一个纯文本信息: void setLatestMessage(Message message) { … if(message.getContentType().startsWith("text/plain")) { latestMessage=new
RenderablePlainText(message); } else { latestMessage=new RenderableMessage(message); } 在程式段使用 startsWith 比较邮件类型.虽然信息内容的类型字符串包含非常多信息,但我们只关心的是 起始部分.例如,我们已建立一个名为 Renderable 的接口,这一接口可查看被解码的邮件,他包括邮件主 题,邮件文本及附件.我们使用 RenderablePlainText 类来解码文本信息,而附件能被忽略.如果查看 RenderablePlainText
构造器,能看到读取内容的过程: public RenderablePlainText(Message message) throws MessagingException, IOException { subject=message.getSubject().substring("MailPage:".length()); bodytext=(String)message.getContent(); } 邮件主题非常容易获得.请注意 Part 接口是来自于前面的文章,即通过这一接口我们将 BodyPart
和 MimeBodyPart 构建一个信息.当解码邮件时,必须使用 Message 方法处理 Parts 的层次. 处理 MultiPart 信息的过程相对比较复杂.MultiPart 意味着 Part 由多个部分组成,每一部分的内容必须接 收到.例如,我们使用 RenderableMessage 类解析 HTML 文本和附件信息. public RenderableMessage(Message m) throws MessagingException,IOException { subject=m.getSubject().substring("MailPage:".length());
attachments=new ArrayList();
extractPart(m); } RenderableMessage 是个简单的 handler,他能够反复调用 Parts 以检查我们是否使用 extractPart 方法. 首先 RenderableMessage 检查给定的 Part 是否是个 MultiPart,如果是,则运行这些子部分并调用 extractPart: private void extractPart(final Part part) throws MessagingException, IOException { if(part.getContent()
instanceof Multipart) { Multipart mp=(Multipart)part.getContent(); for(int i=0;i 然后,我们采用前面处理纯文本的方法来处理 text/html 的内容. if(part.getContentType().startsWith("text/html")) { if(bodytext==null) { bodytext=(String)part.getContent(); } else { bodytext=bodytext+"<HR/>"+(String)part.getContent();
} } 这里没有什么特别.对于多个 text/html 部分,其原始文本将被连成一个长字符串.目前能得到这一过程的 关键之处: else if(!part.getContentType().startsWith("text/plain")) { Attachment attachment=new Attachment(); attachment.setContenttype(part.getContentType()); attachment.setFilename(part.getFileName());
如果内容不是纯文本,将其当成附件,并建立我们的 Attachment instance(即包含文件名,内容类型及内容 的字节),并导入内容类型和文件名.我们将建立一个 ByteArrayOutputStream: InputStream in=part.getInputStream(); ByteArrayOutputStream bos=new ByteArrayOutputStream(); 然后复制内容: byte[] buffer=new byte[8192]; int count=0; while((count=in.read(buffer))>=0)
bos.write(buffer,0,count); in.close(); 最后,从 ByteArrayOutputStream 设置我们的 Attachment instance 的内容,并将 Attachment 添加到附 件的 ArrayList: attachment.setContent(bos.toByteArray()); attachments.add(attachment); } } 以上就是获得附件的过程.当你运行 MailRetriever 并获得最新信息时,MailRetriever
的 main 方法运行 MailRetriever,即提供用户名,密码,服务器名及 provider 类型作为参数.以下为运行 MailRetriever 后的 输出:
Subject:Mail with attachments Body Text:<HTML> <BODY>Here's some images of the <B>Space Shuttle</B>. <DIV><BR class="khtml-block-placeholder"></DIV> <DIV><IMG src="cid:A30781A5-E965-4A36-96FB-70206218303D@local"></DIV> <DIV><IMG src="cid:0A960B93-A970-4F56-8B02-820969A26643@local"></DIV>
</BODY></HTML> 2 attachments 9603752.jpg 81312 bytes of (image/jpeg; x-unix-mode=0644; name=9603752.jpg) 1976_04380L.jpg 32089 bytes of (image/jpeg; x-unix-mode=0644; name=1976_04380L.jpg) 此时, 附件为两张图片. 请注意在信息的 HMTL 文本顶部, <IMG>并非指的是图片文件名, 而是 cid: URLs. 在下一次我们将介绍包含
MailRetriever 代码来处理这一方面的内容. 运行以上例子程式之后,会出现一个警告,即告诉邮件服务器 JavaMail 有漏洞,能使用 FAQ 处理这一漏 洞.当我开始编写这篇文章时,我决定使用 Gmail,Google 邮件服务及 POP3 支持.然而出乎我的意料, Google 的 POP3 服务和 RFC 不兼容,即只要读取一个来自 RFC 的信息,无论怎么操作,这一信息马上 消失.对于其他邮件服务器,邮件服务器版本在解析 RFC 标准时总会提示一个逻辑错误,怎么处理这一问 题?其中一个有效方法就是使用
JavaMail 调试,即当进入到 Session 时,调用 setDebug 方法来调试,可 获得所有的邮件信息.当收取附件时,如果附件太大,在调试时能将系统的属性"mail.debug"设置为 true. JavaMail 包含影响 provider 行为的所有属性.例如,使用 POP3,标准 provider 的属性包括超时设定,认 证及怎么和邮件服务器相互通讯.由此可解决以上提及的兼容问题.然而使用标准 POP3,有些 POP3 providers 会自动地删除已有信息,然而 POP3 REST 命令能将邮件箱处于最初的读信状态.将属性
mail.pop3.rsetbeforequit 设置为 true 可激活 POP3 provider 的行为.属性名的"pop3s"部分代表 provider 名称,所以你可将名称改为"pop3s".以下为代码示例: Properties props=System.getProperties(); props.setProperty("mail.pop3s.rsetbeforequit","true"); props.setProperty("mail.pop3.rsetbeforequit","true");
session=Session.getInstance(props,null); session.setDebug(true); 下个月,我们将介绍使用 MailRetriever 来完成收取附件的过程,及处理其他类型的邮件,比如大容量的附 件. 你能在此下载本文的原始码.

下面这个可能有点小问题 - 但126的没有发现问题。

package com.email.receive;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
import java.io.*;
/*
 Title: 使用JavaMail接收邮件
 Description: 实例JavaMail包接收邮件,本实例没有实现接收邮件的附件。
 Copyright: Copyright (c) 2003
 Filename: POPMail.java
 @version 1.0
 */
public class ReceiveEmail{
 /*
方法说明:主方法,接收用户输入的邮箱服务器、用户名和密码
输入参数:
返回类型:
*/
 public static void main(String args[]){
  try{
   String popServer="pop3.sina.com";    //邮件服务器
   String popUser="user";     //根据自已的用户名修改
   String popPassword="pass";   //根据自已的密码修改
   receive(popServer, popUser, popPassword);
  }catch (Exception ex){
   System.out.println("Usage: java com.lotontech.mail.POPMail"+" popServer popUser popPassword");
  }
  System.exit(0);
 }
 /*
方法说明:接收邮件信息
输入参数:
返回类型:*/
 public static void receive(String popServer, String popUser, String popPassword){
  Store store=null;
  Folder folder=null;
  try{
   //获取默认会话
   Properties props = System.getProperties();
   Session session = Session.getDefaultInstance(props, null);
   //使用POP3会话机制,连接服务器
   store = session.getStore("pop3");
   store.connect(popServer, popUser, popPassword);
   //获取默认文件夹
   folder = store.getDefaultFolder();
   if (folder == null) throw new Exception("No default folder");
   //如果是收件箱
   folder = folder.getFolder("INBOX");
   if (folder == null) throw new Exception("No POP3 INBOX");
   //使用只读方式打开收件箱
   folder.open(Folder.READ_ONLY);
   //得到文件夹信息,获取邮件列表
   Message[] msgs = folder.getMessages();
   for (int msgNum = 0; msgNum < msgs.length; msgNum++){
    printMessage(msgs[msgNum]);
   }
  }catch (Exception ex){
   ex.printStackTrace();
  }
  finally{
   //释放资源
   try{
    if (folder!=null) folder.close(false);
    if (store!=null) store.close();
   }catch (Exception ex2) {
    ex2.printStackTrace();
   }
  }
 }
 /*
方法说明:打印邮件信息
输入参数:Message message 信息对象
返回类型:
  */
 public static void printMessage(Message message){
  try{
   //获得发送邮件地址
   String from=((InternetAddress)message.getFrom()[0]).getPersonal();
   if (from==null) from=((InternetAddress)message.getFrom()[0]).getAddress();
   System.out.println("FROM: "+from);
   //获取主题
   String subject=message.getSubject();
   System.out.println("SUBJECT: "+subject);
   //获取信息对象
   Part messagePart=message;
   Object content=messagePart.getContent();
   //附件
   if (content instanceof Multipart){
    messagePart=((Multipart)content).getBodyPart(0);
    System.out.println("[ Multipart Message ]");
   }
   //获取content类型
   String contentType=messagePart.getContentType();
   //如果邮件内容是纯文本或者是HTML,那么打印出信息
   System.out.println("CONTENT:"+contentType);
   if (contentType.startsWith("text/plain")||
     contentType.startsWith("text/html")){
    InputStream is = messagePart.getInputStream();
    BufferedReader reader=new BufferedReader(new InputStreamReader(is));
    String thisLine=reader.readLine();
    while (thisLine!=null){
     System.out.println(thisLine);
     thisLine=reader.readLine();
    }
   }
   System.out.println("-------------- END ---------------");
  }catch (Exception ex){
   ex.printStackTrace();
  }
 }
}

厄尔,这个报错,下面的 - (当邮件内容为html或其它时报错)

package com.util.mail;

import java.io.FileOutputStream;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;

/** 
* 邮件接受测试 

*/ 
public class POP3MailReceiverTest { 

    public POP3MailReceiverTest() { 
        try { 
            // 1. 设置连接信息, 生成一个 Session 
            Properties props = new Properties(); 
            props.put("mail.transport.protocol", "pop3");// POP3 收信协议 
            props.put("mail.pop.port", "110"); 
            // props.put("mail.debug", "true");// 调试 

            Session session = Session.getInstance(props); 

            // 2. 获取 Store 并连接到服务器 
            Store store = session.getStore("pop3"); 
            store.connect("pop3.126.com", "lajixiang11@126.com", "135246"); 
            // 3. 通过 Store 打开默认目录 Folder 
            Folder folder = store.getDefaultFolder();// 默认父目录 
            if (folder == null) { 

                System.out.println("服务器不可用"); 
                return; 
                // System.exit(1); 
            } 

//            System.out.println("默认信箱名:" + folder.getName()); 
// 
//            Folder[] folders = folder.list();// 默认目录列表 
// 
//            System.out.println("默认目录下的子目录数: " + folders.length); 

            Folder popFolder = folder.getFolder("INBOX");// 获取收件箱 
            popFolder.open(Folder.READ_WRITE);// 可读邮件,可以删邮件的模式打开目录 
            // 4. 列出来收件箱 下所有邮件 
            Message[] messages = popFolder.getMessages(); 
            // 取出来邮件数 
            int msgCount = popFolder.getMessageCount(); 
            System.out.println("共有邮件: " + msgCount + "封"); 

            // FetchProfile fProfile = new FetchProfile();// 选择邮件的下载模式, 
            // 根据网速选择不同的模式 
            // fProfile.add(FetchProfile.Item.ENVELOPE); 
            // folder.fetch(messages, fProfile);// 选择性的下载邮件 

            // 5. 循环处理每个邮件并实现邮件转为新闻的功能 
            for (int i = 0; i < msgCount; i++) { 
                Message msg = messages[i];// 单个邮件 
                // 发件人信息 
                Address[] froms = msg.getFrom(); 
                if(froms != null) { 
                    System.out.println("发件人信息:" + froms[0]); 
                    InternetAddress addr = (InternetAddress)froms[0]; 
                    System.out.println("发件人地址:" + addr.getAddress()); 
                    System.out.println("发件人显示名:" + addr.getPersonal()); 
                } 
                News news = new News();// 生成新闻对象 
                System.out.println("邮件主题:" + msg.getSubject()); 
                news.setTitle(msg.getSubject()); 

                // getContent() 是获取包裹内容, Part 相当于外包装 
                Multipart multipart = (Multipart) msg.getContent();// 获取邮件的内容, 就一个大包裹, 
                                                                // MultiPart 
                                                                    // 包含所有邮件内容(正文+附件) 
                System.out.println("邮件共有" + multipart.getCount() + "部分组成"); 

                // 依次处理各个部分 
                for (int j = 0, n = multipart.getCount(); j < n; j++) { 
                    System.out.println("处理第" + j + "部分"); 
                    Part part = multipart.getBodyPart(j);//解包, 取出 MultiPart的各个部分, 每部分可能是邮件内容, 
                    // 也可能是另一个小包裹(MultipPart) 

                    // 判断此包裹内容是不是一个小包裹, 一般这一部分是 正文 Content-Type: multipart/alternative 
                    if (part.getContent() instanceof Multipart) { 
                        Multipart p = (Multipart) part.getContent();// 转成小包裹 
                        System.out.println("小包裹中有" + p.getCount() + "部分"); 
                        // 列出小包裹中所有内容 
                        for (int k = 0; k < p.getCount(); k++) { 
                            System.out.println("小包裹内容:" + p.getBodyPart(k).getContent()); 
                            System.out.println("内容类型:" 
                                    + p.getBodyPart(k).getContentType()); 
                            if(p.getBodyPart(k).getContentType().startsWith("text/plain")) { 
                                // 处理文本正文 
                                news.setBody(p.getBodyPart(k).getContent() + ""); 
                            } else { 
                                // 处理 HTML 正文 
                                news.setBody(p.getBodyPart(k).getContent() + ""); 
                            } 
                        } 
                    } 

                    // Content-Disposition: attachment;    filename="String2Java.jpg" 
                    String disposition = part.getDisposition();// 处理是否为附件信息 
                    if (disposition != null) { 

                        System.out.println("发现附件: " + part.getFileName()); 
                        System.out.println("内容类型: " + part.getContentType()); 
                        System.out.println("附件内容:" + part.getContent()); 
                        java.io.InputStream in = part.getInputStream();// 打开附件的输入流 
                        // 读取附件字节并存储到文件中 
                        java.io.FileOutputStream out = new FileOutputStream(part.getFileName()); 
                        int data; 
                        while((data = in.read()) != -1) { 
                            out.write(data); 
                        } 
                        in.close(); 
                        out.close(); 
                    } 
                } 
                // } 
                // TODO newsDAO.save(news); // 将邮件所携带的信息作为新闻存储起来 

                // 6. 删除单个邮件, 标记一下邮件需要删除, 不会真正执行删除操作 
                // msg.setFlag(Flags.Flag.DELETED, true); 
            } 

            // 7. 关闭 Folder 会真正删除邮件, false 不删除 
            popFolder.close(true); 
            // 8. 关闭 store, 断开网络连接 
            store.close(); 
        } catch (NoSuchProviderException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } catch (Exception e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
    } 

    /** 
     * @param args 
     */ 
    public static void main(String[] args) { 
        new POP3MailReceiverTest(); 

    } 

}

有一个:

JavaMail:集收发邮件、下载附件功能的简单Web应用(修改)

2010-07-27 22:41:35

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://haolloyin.blog.51cto.com/1177454/361200

在前面的文章 JavaMail:在Web应用下完整接收、解析复杂邮件 中只是实现了基本的登录邮箱、查看邮件、下载附件的功能而已,就少了个在线编辑邮件正文并发送的功能,总是感觉不够意思,所以花点时间再写了几个
HTML 、JSP 文件把这个基本功能也添加进去。

下面的功能是为了和上篇文章中的邮件接收、解析功能合并的,具体的内容可以浏览 JavaMail:在Web应用下完整接收、解析复杂邮件 。如此一来,输入邮箱相关信息并登录邮箱,就能同时编辑邮件和浏览邮箱中的所有邮件以及下载附件了。

需求:

1、提供一个邮箱用户名、密码登录的页面,此时得有一个邮箱类型的下拉框可选,例如我们平常所用的邮箱有:163、126、qq、sina、sohu 等等;如下图:

send_receive01

2、填写了邮箱信息后弹出编辑纯文本邮件正文的页面(关于同时上传附件的功能再找个时间也实现一下,呵呵…),此时页面的下半部分则是直接连接 POP3 服务器获得邮箱中的所有邮件,如下图:

send_receive02

 

3、编辑好邮件的纯文本正文内容之后,则可点击“发送”按钮将邮件发送出去了。

注:在我的代码中,与 SMTP 服务器的连接、用户身份认证是在点击“发送”之后才引发的,这与上面的连接 POP3 服务器获取邮箱所有邮件的设计决定时机不同,看看代码就清楚了,如下图:

 

下面这张截图是乱码未解决之前在控制台打印出的结果,看一下下面的 ???跟上面框起来的正文,就是这里除了问题。

send_receive04

上面是启动 Tomcat 服务器之后的控制台,由于 setDebug(true) 所以会输出与 SMTP 服务器通信的过程中的交互信息,看样子是发送成功了。登录 test_hao@sina.cn 邮箱查看邮件是否发送成功,如下图:

 

下面仍然是乱码未解决之前的截图:send_receive06

嗯嗯,邮件时收到了,可是邮件中的中文乱码了,这个问题暂时还找不出原因,得再考虑考虑…

其实,乱码的原因在于下面的代码中 sendMails.jsp
文件标上背景颜色的一句代码,需要将 HTML 页面请求的编码显式地设置为 GBK 或 gb2312,即 request.setCharacterEncoding("gbk"); 这样子从 writeMails.html 页面获得的 subject 和 body 才不会以默认的编码方式传入进来。

下面是具体的代码实现,省略了上一篇文章中的所有内容,此外,代码中有好几处是默认写上了邮箱的用户名、密码,以及收件人的邮箱地址,下面有标出来了。

程序代码:

index.html 

  1. <hmtl> 
  2.     <head> 
  3.         <title>蚂蚁-->邮箱登录页面</title> 
  4.     </

抱歉!评论已关闭.