JAVA项目四:邮件发送客户端,java邮件发送客户端
JAVA项目四:邮件发送客户端,java邮件发送客户端
一、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.html
session = 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, "邮件发送成功。");
}
}
运行效果:
三、遇到的问题
1、Could not connect to SMTP host: localhost, port: 25;
问题原因:SMTP服务主机没有正确配置
解决办法:配置正确的SMTP服务主机,保证服务连接上
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)); //发送邮件
灵感来自博客:解决办法
2、邮箱要开启SMTP服务,否则会导致无法发送邮件或者邮件会被存入垃圾箱。百度一下就能找到邮箱开启SMTP的方法。
相关文章
- 暂无相关文章
用户点评