JavaMail读发邮件
来源:互联网 发布:印度超级联赛直播数据 编辑:程序博客网 时间:2024/06/08 09:34
http://log-cd.iteye.com/blog/421229
一、基本概念:
SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议,它定义了发送电子邮件的机制。在 JavaMail API 环境中,基于 JavaMail 的程序将和您的公司或因特网服务供应商的(Internet Service Provider's,ISP's)SMTP 服务器通信。SMTP 服务器可将消息中转至接收方 SMTP 服务器,以便最终让用户经由 POP 或 IMAP 获得。这不是要求 SMTP 服务器成为开放的中继,尽管 SMTP 服务器支持身份验证,不过还是得确保它的配置正确。像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMail API 中并不支持。
POP(Post Office Protocol),即邮局协议。目前用的是版本3,所以人们通常将它称为 POP3,RFC 1939 定义了这个协议。POP 和SMTP一样,也是一种机制,Internet上大多数人通过它得到邮件。该协议规定每个用户只能有一个邮箱的支持。这就是它所能做的,而这也造成了许多混淆。使用 POP 时,用户熟悉的许多性能并不是由 POP 协议支持的,如查看有几封新邮件消息这一性能。这些性能内建于如 Eudora 或 Microsoft Outlook 之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。所以当使用 JavaMail API 时,如果读者想要这类信息,就只能由自己来计算了。
IMAP(Internet Message Access Protocol),即Internet消息访问协议,是更高级的用于接收消息的协议,在 RFC 2060 中有它的定义。目前使用的IMAP版本为4,人们习惯将它称为 IMAP4。在用到 IMAP 时,邮件服务器必需支持这个协议。不能仅仅把使用 POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假设邮件服务器支持 IMAP,基于 JavaMail 的程序可以利用这种情况--用户在服务器上可以有多个文件夹(folder),并且这些文件夹可以被多个用户共享。
因为有这一更高级的性能,您也许会认为所有用户都会使用 IMAP。事实并不是这样。要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。使用 POP,就能卸载邮件服务器上保存的消息了。
MIME(Multipurpose Internet Mail Extensions),即多用途Internet邮件扩展标准。它不是邮件传输协议,而是对传输内容的消息、附件及其它的内容定义了格式。这里有很多不同的RFC(Requirement of Comment)文档:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作为一个 JavaMail API 的用户,您通常不必对这些格式操心。无论如何,一定存在这些格式而且程序会用到它。
二、例子
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.security.Security;
- import java.util.Date;
- import java.util.Enumeration;
- import java.util.Properties;
- import java.util.Vector;
- import javax.activation.DataHandler;
- import javax.activation.FileDataSource;
- import javax.mail.Authenticator;
- import javax.mail.BodyPart;
- import javax.mail.FetchProfile;
- import javax.mail.Folder;
- import javax.mail.Message;
- import javax.mail.MessagingException;
- import javax.mail.Multipart;
- import javax.mail.Part;
- import javax.mail.PasswordAuthentication;
- import javax.mail.Session;
- import javax.mail.Store;
- import javax.mail.Transport;
- import javax.mail.URLName;
- import javax.mail.internet.AddressException;
- 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;
- /**
- * 使用Gmail发送邮件
- */
- public class GmailSenderAndFetch {
- private static String messageContentMimeType = "text/html; charset=gb2312";
- private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
- public static Properties getProperties() {
- Properties props = System.getProperties();
- props.setProperty("mail.smtp.host", "smtp.gmail.com");
- // Gmail提供的POP3和SMTP是使用安全套接字层SSL的
- props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
- props.setProperty("mail.smtp.socketFactory.fallback", "false");
- props.setProperty("mail.smtp.port", "465");
- props.setProperty("mail.smtp.socketFactory.port", "465");
- props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY);
- props.setProperty("mail.imap.socketFactory.fallback", "false");
- props.setProperty("mail.imap.port", "993");
- props.setProperty("mail.imap.socketFactory.port", "993");
- props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
- props.setProperty("mail.pop3.socketFactory.fallback", "false");
- props.setProperty("mail.pop3.port", "995");
- props.setProperty("mail.pop3.socketFactory.port", "995");
- props.put("mail.smtp.auth", "true");
- return props;
- }
- /**
- * 构建邮件
- *
- * @param username
- * @param password
- * @param receiver
- * @return
- * @throws AddressException
- * @throws MessagingException
- */
- @SuppressWarnings( { "unchecked", "serial" })
- public static Message buildMimeMessage(final String username,
- final String password, String receiver) throws AddressException,
- MessagingException {
- Session session = Session.getDefaultInstance(getProperties(),
- new Authenticator() {
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(username, password);
- }
- });
- Message msg = new MimeMessage(session);
- //鉴别发送者,您可以使用setFrom()和setReplyTo()方法。
- //msg.setFrom(new InternetAddress("[发件人]"));
- msg.addFrom(InternetAddress.parse("[发件人]"));//地址来源,没作用?
- msg.setReplyTo(InternetAddress.parse("[回复时收件人]"));//回复时用的地址
- //消息接收者
- msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
- receiver, false));
- msg.setSubject("JavaMail邮件发送");
- msg.setSentDate(new Date());
- String content = "How are you!这是一个测试!";
- // 邮件内容数据(Content)
- msg.setContent(buildMimeMultipart(content, new Vector() {
- {
- add("D:/uploadDir/test.txt");
- }
- }));
- return msg;
- }
- /**
- * 构建邮件的正文和附件
- *
- * @param msgContent
- * @param attachedFileList
- * @return
- * @throws MessagingException
- */
- public static Multipart buildMimeMultipart(String msgContent,
- Vector attachedFileList) throws MessagingException {
- Multipart mPart = new MimeMultipart();// 多部分实现
- // 邮件正文
- MimeBodyPart mBodyContent = new MimeBodyPart();// MIME邮件段体
- if (msgContent != null) {
- mBodyContent.setContent(msgContent, messageContentMimeType);
- } else {
- mBodyContent.setContent("", messageContentMimeType);
- }
- mPart.addBodyPart(mBodyContent);
- // 附件
- String file;
- String fileName;
- if (attachedFileList != null) {
- for (Enumeration fileList = attachedFileList.elements(); fileList
- .hasMoreElements();) {
- file = (String) fileList.nextElement();
- fileName = file.substring(file.lastIndexOf("/") + 1);
- MimeBodyPart mBodyPart = new MimeBodyPart();
- //远程资源
- //URLDataSource uds=new URLDataSource(http://www.iteye.com/logo.gif);
- FileDataSource fds = new FileDataSource(file);
- mBodyPart.setDataHandler(new DataHandler(fds));
- //mBodyPart.setFileName(fileName);
- mBodyPart.setFileName(javax.mail.internet.MimeUtility.encodeWord(fileName));//解决中文附件名问题
- mPart.addBodyPart(mBodyPart);
- }
- }
- return mPart;
- }
- /**
- * 字串解码
- *
- * @param text
- * @return
- * @throws UnsupportedEncodingException
- */
- protected static String decodeText(String text)
- throws UnsupportedEncodingException {
- if (text == null)
- return null;
- if (text.startsWith("=?GB") || text.startsWith("=?gb")) {
- text = MimeUtility.decodeText(text);
- } else {
- text = new String(text.getBytes("ISO8859_1"));
- }
- return text;
- }
- /**
- * 分析邮件
- *
- * @param mPart
- */
- public static void parseMailContent(Object content) {
- try {
- if (content instanceof Multipart) {
- Multipart mPart = (MimeMultipart) content;
- for (int i = 0; i < mPart.getCount(); i++) {
- extractPart((MimeBodyPart) mPart.getBodyPart(i));
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 抽取内容
- *
- * @param part
- */
- public static void extractPart(MimeBodyPart part) {
- try {
- String disposition = part.getDisposition();
- if (disposition != null
- && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {// 附件
- String fileName = decodeText(part.getFileName());
- System.out.println(fileName);
- saveAttachFile(part);//保存附件
- } else {// 正文
- if(part.getContent() instanceof String){//接收到的纯文本
- System.out.println(part.getContent());
- }
- if(part.getContent() instanceof MimeMultipart){//接收的邮件有附件时
- BodyPart bodyPart = ((MimeMultipart) part.getContent()).getBodyPart(0);
- System.out.println(bodyPart.getContent());
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 保存附件
- * @param part
- */
- public static void saveAttachFile(Part part){
- try{
- if(part.getDisposition()==null) return;
- String dir="D:/uploadDir/";
- String filename = decodeText(part.getFileName());
- InputStream in=part.getInputStream();
- OutputStream out = new FileOutputStream(new File(dir+filename));
- byte [] buffer=new byte[8192];
- while(in.read(buffer) != -1){
- out.write(buffer);
- }
- in.close();
- out.flush();
- out.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- /**
- * 发送邮件
- *
- * @throws AddressException
- * @throws MessagingException
- */
- public static void sendMail() throws AddressException, MessagingException {
- Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
- //Transport 是用来发送信息的
- Transport.send(buildMimeMessage("[用户名]", "[邮箱密码]",
- "[收件地址]"));
- System.out.println("Message send...");
- }
- /**
- * 取邮件信息
- *
- * @throws Exception
- */
- public static void fetchMail() throws Exception {
- Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
- Session session = Session.getDefaultInstance(getProperties(), null);
- //用pop3协议:new URLName("pop3", "pop.gmail.com", 995, null,"[邮箱帐号]", "[邮箱密码]");
- //用IMAP协议
- URLName urln = new URLName("imap", "imap.gmail.com", 995, null,
- "[邮箱帐号]", "[邮箱密码]");
- Store store = null;
- Folder inbox = null;
- try {
- //Store用来收信,Store类实现特定邮件协议上的读、写、监视、查找等操作。
- store = session.getStore(urln);
- store.connect();
- inbox = store.getFolder("INBOX");//收件箱
- inbox.open(Folder.READ_ONLY);
- FetchProfile profile = new FetchProfile();
- profile.add(FetchProfile.Item.ENVELOPE);
- Message[] messages = inbox.getMessages();
- inbox.fetch(messages, profile);
- System.out.println("收件箱的邮件数:" + messages.length);
- System.out.println("未读邮件数:" + inbox.getUnreadMessageCount());
- System.out.println("新邮件数:" + inbox.getNewMessageCount());
- for (int i = 0; i < messages.length; i++) {
- // 邮件发送者
- String from = decodeText(messages[i].getFrom()[0].toString());
- InternetAddress ia = new InternetAddress(from);
- System.out.println("FROM:" + ia.getPersonal() + '('
- + ia.getAddress() + ')');
- // 邮件标题
- System.out.println("TITLE:" + messages[i].getSubject());
- // 邮件内容
- parseMailContent(messages[i].getContent());
- // 邮件大小
- System.out.println("SIZE:" + messages[i].getSize());
- // 邮件发送时间
- System.out.println("DATE:" + messages[i].getSentDate());
- }
- } finally {
- try {
- inbox.close(false);
- } catch (Exception e) {
- }
- try {
- store.close();
- } catch (Exception e) {
- }
- }
- }
- }
三、如何实现消息的删除
消息的删除涉及到与消息相关的 Flags(标志)。不同 flag 表示不同的状态,有些标志由系统定义,而有些则由用户自己定义。下面列出在内部类 Flags.Flag 中预定义的标志:
·Flags.Flag.ANSWERED
·Flags.Flag.DELETED
·Flags.Flag.DRAFT
·Flags.Flag.FLAGGED
·Flags.Flag.RECENT
·Flags.Flag.SEEN
·Flags.Flag.USER
上述这些标志只是标准定义,并不意味着所有邮件服务器或供应商都支持所有这些标志。例如,除了删除消息标志外,POP 协议不再支持其它任何标志。检查是否存在新邮件,这不是个 POP 任务,而是内建于邮件客户机的任务。为找出哪些标志能被支持,可以用 getPermanentFlags() 向 folder 提出请求。
要删除消息,您可以设置消息的 DELETED flag:
message.setFlag(Flags.Flag.DELETED, true);
首先,请以 READ_WRITE 模式打开 folder:
folder.open(Folder.READ_WRITE);
然后,当所有消息的处理完成后,关闭 folder,并传递一个 true 值,从而擦除(expunge)有 delete 标志的消息。
folder.close(true);
一个 Folder 的 expunge() 方法可以用来删除消息。但 Sun 的 POP3 供应商不支持。其它供应商有的或许能够实现这一功能,而有的则不能。IMAP 供应商极有可能实现此功能。因为 POP 只支持单个对邮箱的访问,对 Sun 的供应商来说,您必需关闭 folder 以删除消息。
要取消标志,只要传递 false 给 setFlag() 方法就行了。想知道是否设置过标志,可以用 isSet() 检查。
- javamail读发邮件
- JavaMail读发邮件
- 用javamail发邮件
- JavaMail API发邮件
- javamail发邮件
- javaMail发邮件
- 用javamail 发邮件
- 用javamail 发邮件
- JAVAMAIL发邮件
- 用JAVAMAIL 发邮件
- javamail发邮件
- javamail发邮件异常
- javamail发邮件乱码
- javamail 发邮件 附件
- javamail发邮件
- javamail发邮件全过程
- javaMail发邮件demo
- javamail发( 收)邮件
- linux守护进程实现
- HDU---开门人和关门人---1234
- VS2008 MFC 与CUDA5.0环境设置及程序运行
- mongodb启动不了
- 2011-12-02 08:41 MFC添加鼠标移动到控件上时的提示信息
- JavaMail读发邮件
- eclipse svn插件 将一个项目中的修改提交到两外一个svn路径上去
- NSFileHandle
- IOS应用程序文件目录的操作
- cocox2d-x HelloWorld分析
- Object-c学习之路十二(OC的copy)
- Set接口
- C++中虚表指针的存放位置
- HDU 4620