一、Java Mail API简介
JavaMail API是读取、撰写、发送电子信息的可选包。我们可用它来建立如Eudora、Foxmail、MS Outlook Express一般的邮件用户代理程序(Mail User Agent,简称MUA)。而不是像sendmail或者其它的邮件传输代理(Mail Transfer Agent,简称MTA)程序那样可以传送、递送、转发邮件。从另外一个角度来看,我们这些电子邮件用户日常用MUA程序来读写邮件,而MUA依赖着MTA处理邮件的递送。
JavaMail核心类:Session、Message、Address、Authenticator、Transport、Store、Folder。
Session类:定义了基本的邮件会话。就像Http会话那样,我们进行收发邮件的工作都是基于这个会话的。Session对象利用了Java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。
Message类: SUN提供了Message类型来帮助开发者完成这项工作。由于Message是一个抽象类,大多数情况下,我们使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的邮箱信息。信息头只能使用US-ASCII字符,而非ASCII字符将通过编码转换为ASCII的方式使用
Address类:到这里,我们已经建立了Session和Message,下面将介绍如何使用邮件地址类:Address。像Message一样,Address类也是一个抽象类,所以我们将使用javax.mail.internet.InternetAddress这个子类。
Authenticator类:像java.NET类那样,JavaMail API通过使用授权者类(Authenticator)以用户名、密码的方式访问那些受到保护的资源,在这里“资源”就是指邮件服务器。在javax.mail包中可以找到这个JavaMail的授权者类(Authenticator)。
Transport类:在发送信息时,Transport类将被用到。这个类实现了发送信息的协议(通称为SMTP),此类是一个抽象类,我们可以使用这个类的静态方法send()来发送消息:Transport.send(message);
Store和Folder类:接收邮件和发送邮件很类似都要用到Session。但是在获得Session后,我们需要从Session中获取特定类型的Store,然后连接到Store,这里的Store代表了存储邮件的邮件服务器。在连接Store的过程中,极有可能需要用到用户名、密码
ps:项目要用到jar包:activation.jar和mail.jar.
二、代码实现
项目源码下载地址:点我
package com.hnust.frame;import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Date;
import java.util.Properties;import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Transport;
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;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;public class SendAttachmentMailFrame extends JFrame {/*** */private static final long serialVersionUID = 1L;private JTextArea ta_attachment;private JTextArea ta_text;private JTextField tf_title;private JTextField tf_send;private JTextField tf_receive;private JPasswordField tf_password;/*** Session类是定义了一个基本会话,是Java Mail API最高层入口类。所有其他类都是经由这个Session才得以生效。* Session对象从java.util.Properties对象中获取信息,* 如邮件发送服务器、接收邮件协议、发送邮件协议、用户名、密码及整个应用程序中共享的其他信息* */private Session session;private String sendHost = "localhost";private String sendProtocol="smtp";private String filePathAndName = null;public static void main(String args[]) {EventQueue.invokeLater(new Runnable() {public void run() {try {SendAttachmentMailFrame frame = new SendAttachmentMailFrame();frame.init();frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}public SendAttachmentMailFrame() {super();setTitle("发送带附件的邮件");getContentPane().setLayout(null); //设置布局为空布局setBounds(200, 200, 480, 400);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);final JLabel label = new JLabel();label.setForeground(new Color(0, 0, 255));label.setFont(new Font("", Font.BOLD, 22));label.setText("@发送带附件的邮件@");label.setBounds(123, 10, 230, 24);getContentPane().add(label);final JLabel label_1 = new JLabel();label_1.setText("收件人地址:");label_1.setBounds(22, 42, 85, 18);getContentPane().add(label_1);tf_receive = new JTextField();tf_receive.setBounds(113, 40, 287, 22);getContentPane().add(tf_receive);final JLabel label_2 = new JLabel();label_2.setText("发件人邮箱:");label_2.setBounds(22, 68, 78, 18);getContentPane().add(label_2);tf_send = new JTextField();tf_send.setBounds(113, 66, 287, 22);getContentPane().add(tf_send);final JLabel label_2_1 = new JLabel();label_2_1.setText("邮箱密码:");label_2_1.setBounds(30, 95, 78, 18);getContentPane().add(label_2_1);tf_password = new JPasswordField();tf_password.setBounds(113, 95, 278, 18);getContentPane().add(tf_password);final JLabel label_3 = new JLabel();label_3.setText("主 题:");label_3.setBounds(32, 125, 66, 18);getContentPane().add(label_3);tf_title = new JTextField();tf_title.setBounds(113, 125, 287, 22);getContentPane().add(tf_title);final JLabel label_4 = new JLabel();label_4.setText("正 文:");label_4.setBounds(34, 150, 66, 18);getContentPane().add(label_4);//创建一个空的(无视口的视图)JScrollPane,需要时水平和垂直滚动条都可显示final JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(113, 150, 287, 76);getContentPane().add(scrollPane);ta_text = new JTextArea();//创建一个视口(如果有必要)并设置其视图scrollPane.setViewportView(ta_text);final JButton btn_send = new JButton();btn_send.addActionListener(new ActionListener() {public void actionPerformed(final ActionEvent e) {String fromAddr = tf_send.getText().trim();String toAddr = tf_receive.getText().trim();// 真实存在的目标邮件地址String title = tf_title.getText().trim();String text = ta_text.getText().trim();try {sendMessage(fromAddr, toAddr, title, text); //发送消息} catch (Exception e1) {e1.printStackTrace();}}});btn_send.setText("发 送");btn_send.setBounds(225, 300, 85, 28);getContentPane().add(btn_send);//添加发送按钮到容器final JButton btn_exit = new JButton();btn_exit.addActionListener(new ActionListener() {public void actionPerformed(final ActionEvent e) {System.exit(0);}});btn_exit.setText("退 出");btn_exit.setBounds(316, 300, 84, 28);getContentPane().add(btn_exit);final JButton button = new JButton(); //添加附件按钮button.addActionListener(new ActionListener() { //点击事件public void actionPerformed(final ActionEvent e) {JFileChooser fileChooser = new JFileChooser(); // 创建文件对话框int returnValue = fileChooser.showOpenDialog(null);// 打开文件选择对话框if (returnValue == JFileChooser.APPROVE_OPTION) { // 判断是否选择了文件File file = fileChooser.getSelectedFile(); // 获得文件对象if (file.length() / 1024.0 / 1024 > 50.0) {JOptionPane.showMessageDialog(null, "请选择小于等于50MB的文件。");return;}filePathAndName = file.getAbsolutePath();// 获得文件的完整路径和文件名ta_attachment.append(file.getName());// 显示附件文件的名称}}});button.setText("添加附件");button.setBounds(113, 300, 106, 28);getContentPane().add(button);final JLabel label_5 = new JLabel();label_5.setText("附 件:");label_5.setBounds(32, 230, 66, 18);getContentPane().add(label_5);//创建一个空的(无视口的视图)JScrollPane,需要时水平和垂直滚动条都可显示final JScrollPane scrollPane_1 = new JScrollPane();scrollPane_1.setBounds(112, 230, 287, 63);getContentPane().add(scrollPane_1);ta_attachment = new JTextArea();//创建一个视口(如果有必要)并设置其视图scrollPane_1.setViewportView(ta_attachment);}public void init() throws Exception {/*** Session对象利用Properties对象获得了邮件发送服务器、接收邮件协议、发送邮件协议、用户名、密码等整个应用程序都要使用到的共享信息* */Properties props = new Properties();/*** put()方法将指定 key 映射到此哈希表中的指定 value。键和值都不可以为 null。 通过使用与原来的键相同的键调用 get 方法,可以获取相应的值* */props.put("mail.transport.protocol", sendProtocol);//发送协议props.put("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport");props.put("mail.smtp.host", "127.0.0.1");//本机地址和域名绑定。否则会出错 详见:http://www.cnblogs.com/zhongzheng123/p/5869554.htmlsession = Session.getDefaultInstance(props);}/*** @param fromAddr 发送方地址* @param toAddr 接收方地址* @param title 主题* @param text 文本内容* @throws Exception 异常*/public void sendMessage(String fromAddr,String toAddr,String title,String text) throws Exception {//Message类封装的邮件信息,提供了访问和设置邮件内容的方法Message msg = new MimeMessage(session);// 创建Message对象/*** 建立了Session和Message对象之后,使用邮件地址Address抽象类的子类:javax.mail.internetAddress * */InternetAddress[] toAddrs = InternetAddress.parse(toAddr,false);// 接收方地址msg.setRecipients(Message.RecipientType.TO, toAddrs);// 指定接收方msg.setSentDate(new Date());// 设置发送日期msg.setSubject(title);// 设置主题msg.setFrom(new InternetAddress(fromAddr));// 设置发送地址Multipart multipart = new MimeMultipart();// 可以添加复杂内容的Multipart对象(Multipart抽象类是保存电子邮件内容的容器)MimeBodyPart mimeBodyPartText = new MimeBodyPart();// 添加正文的MimeBodyPart对象mimeBodyPartText.setText(text);// 指定正文multipart.addBodyPart(mimeBodyPartText);// 添加到Multipart对象上if (filePathAndName!=null && !filePathAndName.equals("")){MimeBodyPart mimeBodyPartAdjunct = new MimeBodyPart();// 添加附件的MimeBodyPart对象FileDataSource fileDataSource = new FileDataSource(filePathAndName);// 创建附件的FileDataSource对象mimeBodyPartAdjunct.setDataHandler(new DataHandler(fileDataSource));// 指定数据mimeBodyPartAdjunct.setDisposition(Part.ATTACHMENT);// 指定添加的内容是附件String name = fileDataSource.getName();mimeBodyPartAdjunct.setFileName(MimeUtility.encodeText(name, "GBK", null));// 指定附件文件的名称multipart.addBodyPart(mimeBodyPartAdjunct);// 添加到Multipart对象上}msg.setContent(multipart);// 设置邮件内容String server = "smtp.163.com"; //设置SMTP服务器(220.181.12.15)String username = tf_send.getText(); //获取发送方的邮箱用户名String password = new String(tf_password.getPassword()); //获取发送方的邮箱密码/*** Transport类根据指定的邮件发送协议(通常是SMTP),通过指定的邮件发送服务器来发送邮件。* Transport类是抽象类,他提供了一个静态方法send(Message)来发送邮件* */ Transport transport = session.getTransport(); transport.connect(server, username, password); //连接服务器transport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO)); //发送邮件filePathAndName = null;JOptionPane.showMessageDialog(null, "邮件发送成功。");}
}
运行效果: