一、JavaMail API简介 JavaMail API是读取、撰写、发送电子信息的可选包。 可用它来建立如Eudora、Foxmail、MS Outlook Express一般的邮件用户代理程序(Mail
User Agent,简称MUA,而非邮件传输代理MTA)。 从另外一个角度来看,我们这些电子邮件用户日常用MUA程序来读写邮件,而MUA依赖着MTA处理邮件的递送。 二、相关协议一览 不依赖于协议的方式发送接收电子信息,只依赖特定协议SMTP、POP、IMAP、MIME、NNTP协议。 1.SMTP(递送邮件机制) 简单邮件传输协议 SMTP服务器将邮件转发到接收者的SMTP服务器,直至最后被接收者通过POP或者IMAP协议获取。 2.POP(获取邮件机制) 邮局协议,目前为第3个版本POP3 3.IMAP(多目录共享) 接收信息的高级协议,目前版本为第4版IMAP4 接收新信息,将这些信息递送给用户,维护每个用户的多个目录。 4.MIME 邮件扩展内容格式:信息格式、附件格式等等 5.NNTP mail.jar文件添加到CLASSPATH中 2.安装JavaBeans Activation Framework 从http://java./products/javabeans/glasgow/jaf.html下载JavaBeans Activation Framework activation.jar文件添加到CLASSPATH中 四、初次认识JavaMail API 1.了解我们的JavaMail环境 A.纵览JavaMail核心类结构 JavaMail.jar文件的一些核心类:Session、Message、Address、Authenticator、Transport、Store、Folder。 以及javax.mail.internet包中还有一些常用的子类。 B.Session(邮件会话) 进行收发邮件的工作都是基于这个会话的。 Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。 Properties props = new Properties();或者 Properties props = new Properties();从上面的两个例子中不难发现,第二个参数都是null,这是因为在上面的例子中并没有使用到邮件授权(参考E) C.Message 建立了Session对象后,便可以被发送的构造信息体Message抽象类 使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的邮箱信息。 信息头只能使用US-ASCII字符 Message message = new MimeMessage(session); message.setContent("Hello", "text/plain");//非文本信息内容 message.setText("Hello");//纯文本信息内容 message.setSubject("First");//设置邮件主题 message.setSentDate(Date);//设置邮件发送日期 D.Address 建立了Session和Message对象后,使用邮件地址Address抽象类 使用javax.mail.internet.InternetAddress这个子类。通过传入邮件地址的字符串 Address address = new InternetAddress("kuangye89757@163.com"); //邮件地址 Address address = new InternetAddress("president@whitehouse.gov", "George Bush"); //带名字的邮件地址 message.setFrom(address);//设置发信人 message.setReplyTo(address);//同上 message.addFrom(Address[] address);//添加多个发信人 message.addRecipient(type, address)//设置收信人 Message.RecipientType.TO//收信人 Message.RecipientType.CC//抄送人 Message.RecipientType.BCC//暗送人 E.Authenticator授权者类 使用Authenticator抽象类必须实现getPasswordAuthentication()方法(用于存储认证时要用到的用户名、密码)。 并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。 Properties props = new Properties(); Authenticator auth = new MyAuthenticator(); Session session = Session.getDefaultInstance(props, auth); /** * 自定义邮件授权类 * @return * @throws IOException */ public class MyAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication(String param) { String username; String password; StringTokenizer st = new StringTokenizer(param, ","); username = st.nextToken(); password = st.nextToken(); return new PasswordAuthentication(username, password); } } F.Transport 发送信息时使用Transport抽象类(实现了SMTP) Transport.send(MimeMessage message); 或者一般用法 当然,方法是多样的。我们也可由Session获得相应协议对应的Transport实例。并通过传递用户名、密码、邮件服务器主机名等参数建立与邮件服务器的连接,并使用sendMessage()方法将信息发送,最后关闭连接: session.setDebug(true);//监控邮件发送过程 message.saveChanges(); //保存文件 Transport transport = session.getTransport("smtp");//获取实现了SMTP协议的Transport类 transport.connect(host, username, password);//连接服务器 transport.sendMessage(message, message.getAllRecipients());//发送邮件给所有收件人 transport.close();//关闭连接 G.Store(存储邮件的服务器)和Folder(目录对象) Store store = session.getStore("pop3"); store.connect(host, username, password); Folder folder = store.getFolder("INBOX");//POP3协议只有一个名为INBOX的Folder有效 folder.open(Folder.READ_ONLY);//只读方式打开 Message message[] = folder.getMessages();//获得邮件 System.out.println(((MimeMessage)message).getContent());//邮件内容(不包含邮件头) System.out.println(((MimeMessage)message).writeTo());//邮件内容(含邮件头) folder.close(true);//若删除邮件则及时更新Folder,关闭 store.close();//关闭 五、使用JavaMail API 1.发送邮件 在获得了Session后,建立并填入邮件信息,在发送邮件之前,我们需要设置SMTP服务器:通过设置Properties的mail.smtp.host属性 mail配置文件.properties String server=xx.xx.xx.xx(服务器) authUser=XXX authPasswd=xxxxxx /** * 获得配置文件信息 * @return * @throws IOException */ private static Properties getProp() throws IOException{ //获得文件存储路径 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream inputStream = classLoader.getResourceAsStream("mail配置文件.properties"); Properties prop = new Properties(); prop.load(inputStream); return prop; } private String from = ...;//发件人 private String to = ...;//收件人 //获取邮件发送服务器及验证用户名和密码 Properties props=getProp(); props.put("mail.smtp.host", host); //获取Session会话 Session session = Session.getDefaultInstance(props, null); //创建MIMEMessage Message message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject("Hello JavaMail"); message.setText("Welcome to JavaMail"); //发送邮件 message.saveChanges(); Transport transport = session.getTransport("smtp"); transport.connect(props.getProperty(“server”), props.getProperty(“authUser”), props.getProperty(“authPasswd”)); transport.sendMessage(message, message.getAllRecipients()); transport.close(); 2.接收邮件 Session session = Session.getDefaultInstance(props, null); Store store = session.getStore("pop3"); store.connect(props.getProperty(“server”), props.getProperty(“authUser”), props.getProperty(“authPasswd”)); Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); Message message[] = folder.getMessages(); for (int i=0, n=message.length; i<n; i++) { System.out.println(i + ": " + message[i].getFrom()[0] + " " + message[i].getSubject()); } folder.close(false); store.close(); 3.删除邮件和标志 Flags类的内部类Flag中预定义了一些标志:(POP协议不支持) 如:Flags.Flag.DELETED 通过访问一个已经打开的Folder对象的getPermanetFlags()方法,它将返回当前被支持的Flags类对象。 删除邮件时,我们可以设置邮件的DELETED标志: if(Message.isSet(Flags.Flag.DELETED)){ folder.open(Folder.READ_WRITE); message.setFlag(Flags.Flag.DELETED, true);//删除邮件 folder.close(true); } 4.回复邮件 MimeMessage reply = (MimeMessage)message.reply(false);//不发送给发件人 reply.setFrom(new InternetAddress("president@whitehouse.gov")); reply.setText("Thanks"); Transport.send(reply);//回复邮件 6.转发邮件 转发邮件的过程不如前面的回复邮件那样简单,它将建立一个转发邮件,这并非一个方法就能做到。 每个邮件是由多个部分(邮件体MimeBodyPart类对象)组成 这些邮件体包含MimeMultiPart类对象 复制一个邮件内容到另一个邮件的方法是复制它的DataHandler(数据处理者) Message forward = new MimeMessage(session); forward.setSubject("Fwd: " + message.getSubject()); forward.setFrom(new InternetAddress(from)); forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); forward.setContent(multipart);//这里的多媒体对象通过下列方式获得 Transport.send(forward);//转发邮件 //创建邮件体对象 BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(“内容”,"text/plain;charset=GB2312"); messageBodyPart.setDataHandler(message.getDataHandler());//从邮件中获取DataHandler //创建多媒体对象 Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); 7.使用附件 A.发送带有附件的邮件建立一个完整邮件的各个邮件体部分: 第一个部分:邮件内容文字 第二个部分:具有DataHandler的附件 1.若文件作为附件发送建立FileDataSource类型的附件数据源对象 2.若URL作为附件发送建立URLDataSource类型的附件数据源对象 Message message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject("Hello JavaMail Attachment"); //第一部分(内容) BodyPart messageBodyPart1 = new MimeBodyPart(); messageBodyPart1.setText("Pardon Ideas"); //第二部分(文件附件) BodyPart messageBodyPart2 = new MimeBodyPart(); DataSource source = new FileDataSource(filename); messageBodyPart2.setDataHandler(new DataHandler(source)); messageBodyPart2.setFileName(filename); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart1);//装填第一部分 multipart.addBodyPart(messageBodyPart2);//装填第二部分 message.setContent(multipart); Transport.send(message);//发送带有附件的文件 使用servlet实现发送带有附件的邮件注意提交页面form中对编码类型的设置应为multipart/form-data <form enctype="multipart/form-data" method=post action="/myservlet"> <input type="file" NAME="thefile"> <input type="submit" VALUE="Upload"> </form> B.读取邮件中的附件 读取邮件中带有附件的邮件是多部分组成的,我们必须处理每一个部分获得邮件的内容和附件 BodyPart类提供了getDisposition()方法获得邮件体的部署类型 该部分是附件时返回Part.ATTACHMENT或Part.INLINE //获取邮件中的多媒体 Multipart mp = (Multipart)message.getContent(); //循环遍历多媒体,并获取邮件体各部分 for (int i=0, n=multipart.getCount(); i<n; i++) { Part part = multipart.getBodyPart(i)); //获得邮件体的部署类型 String disposition = part.getDisposition(); if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE))) { saveFile(part.getFileName(), part.getInputStream()); }else if (disposition == null) { MimeBodyPart mbp = (MimeBodyPart)part; if (mbp.isMimeType("text/plain")) { //解析过程 } else { //其他解析过程 } } } 8.处理HTML邮件 A.发送HTML邮件 设置邮件内容为html代码,并设置内容类型为text/html即可: String htmlText = "<H1>Hello</H1>" + "<img src="http://www./images/logo.gif">"; message.setContent(htmlText, "text/html")); 请注意: 在接收邮件时,因为JavaMail API邮件内容视为二进制流。必须使用JEditorPane if (message.getContentType().equals("text/html")) { String content = (String)message.getContent(); JFrame frame = new JFrame(); JEditorPane text = new JEditorPane("text/html", content); text.setEditable(false); JScrollPane pane = new JScrollPane(text); frame.getContentPane().add(pane); frame.setSize(300, 300); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.show(); } B.在邮件中包含图片 将HTML中用到的图片作为邮件附件并使用特殊的cid URL作为图片的引用(Content-ID头的引用) 通过设置图片附件邮件体部分的header中Content-ID为一个随机字符串, 并在HTML中img的src标记中设置为该字符串来完成了图片附件与HTML的关联。 String file = ...; Message message = new MimeMessage(session); message.setSubject("Embedded Image"); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); // 创建邮件体HTML部分 BodyPart messageBodyPart1 = new MimeBodyPart(); String htmlText = "<H1>Hello</H1>" + "<img src="cid:memememe">"; messageBodyPart1.setContent(htmlText, "text/html"); //创建邮件体img部分 BodyPart messageBodyPart2 = new MimeBodyPart(); DataSource fds = new FileDataSource(file); messageBodyPart2.setDataHandler(new DataHandler(fds)); messageBodyPart2.setHeader("Content-ID","<memememe>"); 9.在邮件中搜索短语 JavaMail API提供了过滤器机制,它被用来建立搜索短语。 使用javax.mail.search包中的SearchTerm抽象类来定义,在定义后我们便可以使用Folder的Search()方法查找邮件: 下面有22个不同的类(继承了SearchTerm类)供我们使用: AND
terms 、OR terms 、NOT terms 、SENT DATE terms、CONTENT terms 、HEADER terms 实例:在Folder中搜索邮件主题含有“ADV”字符串或者发信人地址为friend@public.com的邮件。 SearchTerm st = new OrTerm(new SubjectTerm("ADV:"), new FromStringTerm("friend@public.com"));
|
|
来自: 昵称16088576 > 《JAVA笔记》