JavaMail是Sun发布的处理电子邮件的应用程序接口,它预置了一些最常用的邮件传送协议的实现方法,并且提供了很容易的方法去调用它们。JavaMail是Sun发布的应用程序接口,所以目前它还没有被JDK包含。因此你需要从Sun的官方网站上下载到JavaMail类文件包。除此之外还需要Sun的JAF(JavaBeans Activation Framework ),否则JavaMail将不能运行。
核心JavaMail API 由七个类组成:Session 、Message 、Address 、Authenticator 、Transport 、Store 及 Folder ,它们都来自javax.mail 、即JavaMail API *包。可以用这些类完成大量常见的电子邮件任务,包括发送消息、检索消息、删除消息、认证、回复消息、转发消息、管理附件、处理基于HTML文件格式的消息以及搜索或过滤邮件列表。有关JavaMail 的更多信息,请参考JavaMail 指南。
JavaMail的基础知识
使用JavaMail是发送电子邮件所需要的组件 。
JavaMail的机构使处理电子邮件非常容易。下面列出了一些我们需要的类:
1.Properties
JavaMail需要Properties来创建一个session对象。它将寻找字符串"mail.smtp.host",属性值就是发送邮件的主机,如:
Properties props = new Properties ();
props.put("mail.smtp.host", "smtp.sina.com"); // 可以换上你的smtp主机名。
props.put("mail.smtp.auth", "true"); // 身份验证,目前免费邮件服务器都需要这一项
2.Session
这个Session类代表JavaMail中的一个邮件会话。每一个基于JavaMail的应用程序至少有一个Session(可以有任意多的Session)。在这个例子中,Session对象需要知道用来处理邮件的SMTP服务器。为了做到这一点,你可以参照下面的例子用Properties 来创建一个Session 对象
Session session = Session.getDefaultInstance(props, null);
3.Transport
邮件是既可以被发送也可以被受到。JavaMail使用了两个不同的类来完成这两个功能:Transport 和 Store。 Transport 是用来发送信息的,而Store用来收信。对于这的教程我们只需要用到Transport对象。Store的用法请参看Sun的JavaMail文档。
用法:Transport transport = session.getTransport("smtp");
用JavaMail Session对象的getTransport 方法来初始化Transport。传过去的字符串申明了对象所要使用的协议,如"smtp"。这将为我们省了很多时间。因为JavaMail已经内置了很多协议的实现方法。
注意: JavaMail并不是绝对支持每一个协议,目前支持IMAP、 SMTP和 POP3。
4.Message
Message对象将存储我们实际发送的电子邮件信息,Message对象被作为一个MimeMessage对象来创建并且需要知道应当选择哪一个JavaMail session。
使用方法是:Message message = new MimeMessage(session);
邮件乱码问题:
JavaMail中的邮件主题需要进行BASE64编码,格式形如:=?GBK?B?xPq1xMPcwuvS0b6t1tjWw6Osx+u+ob/stcfCvKOssqLQ3rjEw9zC66Oh?=
所以,直接使用message.setSubject("中文主题"),或者message.setSubject("中文主题".getBytes ("ISO-8859-1"), "GBK"))都一样会出现乱码。在设置邮件主题前需要将主题字串的字节编码为BASE64格式,并添加编码头,示例代码如下:
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
msg.setSubject("=?GBK?B?"+enc.encode(subject.getBytes())+"?=");
邮件发送源码:
SendMail.java
package com.lzw.mail;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
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 com.lzw.io.Out;
/**
* 邮件发送程序
* @author 李赵伟 Create: 2007-12-19
*/
public class SendMail {
private Session session; //会话
private Transport transport; //发送邮件
private User user; //邮件相关的帐户信息
private MailAddress mailAddress; //收件人地址
private MailBody mailBody; //邮件内容
private final String MAIL_SMTP_HOST = "mail.smtp.host";
private final String MAIL_SMTP_AUTH = "mail.smtp.auth";
public SendMail(User user) {
this.user = user;
init();
}
/**
* 初始化<code> Session, Transport </code>
*/
private void init() {
Authenticator auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user.getUsername(), user
.getPassword());
}
};
Properties props = new Properties();
// 设置发送邮件的邮件服务器的属性(这里使用网易的smtp服务器)
props.put(MAIL_SMTP_HOST, user.getHost());
// 需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条)
props.put(MAIL_SMTP_AUTH, "true");
// 用刚刚设置好的props对象构建一个session
session = Session.getDefaultInstance(props, auth);
try {
// 发送邮件
transport = session.getTransport("smtp");
// 连接服务器的邮箱
transport.connect(user.getHost(), user.getUsername(), user
.getPassword());
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
Out.pln("与 " + user.getHost() + " 成功建立会话");
}
/**
* 设置收件人地址
*
* @param mailAddress
*/
public void setAddress(MailAddress mailAddress) {
this.mailAddress = mailAddress;
}
/**
* 设置邮件内容
*
* @param mailBody
*/
public void setMailBody(MailBody mailBody) {
this.mailBody = mailBody;
}
/**
* 构造邮件的内容
*
* @return
* @throws AddressException
* @throws MessagingException
*/
private Message createMessage() throws AddressException, MessagingException {
// 用session为参数定义消息对象
MimeMessage message = new MimeMessage(session);
// 加载发件人地址
message.setFrom(new InternetAddress(user.getFrom()));
message.setSentDate(new Date());
// 加载收件人地址
message.addRecipients(Message.RecipientType.TO, getAddress(mailAddress
.getTo()));
if (mailAddress.isHasCC())
message.addRecipients(Message.RecipientType.CC,
getAddress(mailAddress.getCc()));
// 加载标题
message.setSubject(mailBody.getSubject());
if (mailBody.isContentFlag() || mailBody.isAffixFlag()) {
// 向multipart对象中添加邮件的各个部分内容,包括文本内容和附件
Multipart multipart = new MimeMultipart();
if (mailBody.isContentFlag()) {
// 设置邮件的文本内容
MimeBodyPart contentPart = new MimeBodyPart();
if (mailBody.isMimeContent())
contentPart.setContent(mailBody.getContent(),
"text/html;charset=GBK");
else
contentPart.setText(mailBody.getContent());
multipart.addBodyPart(contentPart);
}
if (mailBody.isAffixFlag()) {
// 添加附件
BodyPart affixBody = new MimeBodyPart();
DataSource source = new FileDataSource(mailBody.getAffix());
// 添加附件的内容
affixBody.setDataHandler(new DataHandler(source));
// 添加附件的标题这里很重要,通过下面的Base64编码的转换可以保证你的
// 中文附件标题名在发送时不会变成乱码
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
String fileName = "=?GBK?B?"
+ enc.encode(mailBody.getAffixName().getBytes()) + "?=";
affixBody.setFileName(fileName);
multipart.addBodyPart(affixBody);
}
// 将multipart对象放到message中
message.setContent(multipart);
}
// 保存邮件
message.saveChanges();
return message;
}
/**
* 发送邮件,包含:邮件正文、(1个附件)
*
* @param debug
* 调试设置
*/
public void send(boolean debug) {
// 有了这句便可以在发送邮件的过程中在console处显示过程信息,供调试使
// 用(你可以在控制台(console)上看到发送邮件的过程)
session.setDebug(debug);
try {
Message message = createMessage();
transport.sendMessage(message, message.getAllRecipients());
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
Out.pln("/n----------------------------------------------------------");
Out.pln("- 邮件成功发送!");
Out.pln("- TO : " + Arrays.toString(mailAddress.getTo()));
if (mailAddress.isHasCC())
Out.pln("- CC : " + Arrays.toString(mailAddress.getCc()));
Out.pln("----------------------------------------------------------/n");
}
/**
* 关闭资源
*
* @throws MessagingException
*/
public void close() throws MessagingException {
if (null != transport)
transport.close();
}
public Address[] getAddress(String[] address) throws AddressException {
Address[] addrs = new InternetAddress[address.length];
for (int i = 0; i < address.length; i++)
addrs[i] = new InternetAddress(address[i]);
return addrs;
}
/**
* 测试
*/
public static void main(String[] args) {
String host = "smtp.sina.com";
String username = "";
String password = "";
// String from = "";
String to = "";
// String cc = null;
String subject = "测试";
String content = "<a href=http://www.baidu.com>baidu</a>";
boolean mimeContent = true;
String affix = "d:/temp/temp.txt";
String affixName = "temp.txt";
boolean debug = false;
// String userFile = "user.properties";
// String addressFile = "mailaddress.properties";
SendMail mail = null;
try {
try {
User user = new User(host, username, password);
MailAddress mailAddress = new MailAddress(to);
// User user = new User(userFile);
// MailAddress mailAddress = new MailAddress(SendMail.class
// .getResourceAsStream(addressFile));
MailBody mailBody = new MailBody(subject, content, mimeContent,
affix, affixName);
mail = new SendMail(user);
// for (int i = 0; i < 5; i++) {
// 设置发件人地址、收件人地址和邮件标题
mail.setAddress(mailAddress);
// 设置要发送附件的位置和标题
mail.setMailBody(mailBody);
// 设置smtp服务器以及邮箱的帐号和密码
mail.send(debug);
// try {
// Thread.sleep(1 * 1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// mailBody = new MailBody(subject + "_" + (i + 1), content);
// }
} finally {
if (null != mail)
mail.close();
}
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
}
}
}
使用JavaMail发送邮件需要注意的地方:
使用免费的邮件服务器发送邮件时,需要对用户的身份做验证;而进行身份验证的过程又比较消耗时间,当用户需要发送多封邮件时如果每次都做身份验证的话时间的消耗是非常大的;
在整个邮件发送过程中Session(会话)的建立只需要一次,也就是说身份验证也只做一次就可以了,即Session session = Session. getDefaultInstance(props, auth);
发送邮件的过程相对比较简单,有一个需要注意的地方就是连接邮件服务器时transport.connect(user.getHost(), user.getUsername(), user.getPassword());也只需要执行一次即可,这个过程和身份验证一样都需要消耗大量时间。
该程序只允许发送带有一个附件的邮件;
文章出处:http://www.diybl.com/course/3_program/java/javajs/20071226/95325.html