效果图:
代码:
EmailClient.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
public class EmailClient extends JFrame {
private JTextField fromTextField;
private JTextField toTextField;
private JTextField subjectTextField;
private JTextArea messageTextArea;
private JButton attachButton;
private JButton sendButton;
private String host;
private String port;
private String username;
private String password;
//关于附件
String encodedFilename;
DataSource source;
public EmailClient() {
setTitle("Email Client");
setDefaultCloseOperation(EXIT_ON_CLOSE);
//setSize(500, 400);
setSize(800, 500);
setLocation(400, 200);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new GridLayout(4, 2));
inputPanel.add(new JLabel("发件人:"));
fromTextField = new JTextField();
inputPanel.add(fromTextField);
inputPanel.add(new JLabel("收件人:"));
toTextField = new JTextField();
inputPanel.add(toTextField);
inputPanel.add(new JLabel("主题:"));
subjectTextField = new JTextField();
inputPanel.add(subjectTextField);
inputPanel.add(new JLabel("邮件正文:"));
messageTextArea = new JTextArea();
inputPanel.add(new JScrollPane(messageTextArea));
attachButton = new JButton("添加附件");
attachButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
int result = chooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
//添加内容
String filename = chooser.getSelectedFile().getName();
System.out.println("附件名称:"+filename);
try {
encodedFilename = MimeUtility.encodeText(filename, "UTF-8", "B");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String path = chooser.getCurrentDirectory().toString();
source = new FileDataSource(path+"\\"+filename);
//添加内容
}
}
});
sendButton = new JButton("发送");
sendButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendEmail();
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(attachButton);
buttonPanel.add(sendButton);
mainPanel.add(inputPanel, BorderLayout.CENTER);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
add(mainPanel);
}
private void sendEmail() {
String from = fromTextField.getText().trim();
String to = toTextField.getText().trim();
String subject = subjectTextField.getText().trim();
String message = messageTextArea.getText().trim();
Properties properties = System.getProperties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.auth", "true");
Session session = Session.getInstance(properties, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(from));
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
mimeMessage.setSubject(subject);
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(message);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
//下面是源程序的增加附件 的一部分,好像是可以添加多个附件!!
/* AttachmentDataSource dataSource = new AttachmentDataSource();
for (int i = 0; i < messageTextArea.getLineCount(); i++) {
String line = messageTextArea.getLineStartOffset(i) + "-" + messageTextArea.getLineEndOffset(i);
dataSource.addAttachment(line);
}
for (String attachment : dataSource.getAttachments()) {
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.attachFile(new File(attachment));
multipart.addBodyPart(attachmentBodyPart);
}*/
//end
//修改后因该加一个判断,当datasource不为空时,才能执行下面内容不然会有空指针异常
if(source!=null) {
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(encodedFilename);
multipart.addBodyPart(attachmentBodyPart);
//
}
mimeMessage.setContent(multipart);
Transport.send(mimeMessage);
JOptionPane.showMessageDialog(this, "邮件发送成功! ");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "邮件发送失败!");
}
}
public static void main(String[] args) {
EmailClient emailClient = new EmailClient();
emailClient.host = "smtp.163.com";
emailClient.port = "465";
emailClient.username = "111@163.com";//填自己的
emailClient.password = " JUABC ";//填自己的
emailClient.setVisible(true);
}
}
class AttachmentDataSource {
private java.util.List<String> attachments;
public AttachmentDataSource() {
attachments = new java.util.ArrayList<String>();
}
public void addAttachment(String attachment) {
attachments.add(attachment);
}
public java.util.List<String> getAttachments() {
return attachments;
}
}
login.java
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
public class login extends JFrame{
public JFrame j;
public JPanel p1,p2,p3;
public JLabel setting,logininfo,lpop3_ip,lpop3_port,lsmtp_ip,lsmtp_port,limap_ip,limap_port,lsmtp_ip1,lsmtp_port1,lemail,lpwd;
public JTextField pop3_ip,pop3_port,smtp_ip,smtp_port,imap_ip,imap_port,smtp_ip1,smtp_port1,email,pwd,blank;
public JButton send, receive, concel;
public JRadioButton jradio1,jradio2;
public login() {
//j=new JFrame("登陆程序");
this.setTitle("服务器端");
this.setLayout(new GridLayout(5, 1));
p1=new JPanel(new BorderLayout());
p2=new JPanel(new FlowLayout(0));
p3=new JPanel(new GridLayout(3, 3));
//标签
setting=new JLabel("邮件服务器设置");
logininfo=new JLabel("登录信息");
lpop3_ip=new JLabel("POP3服务器地址");
lpop3_port=new JLabel("POP3服务器端口号");
lsmtp_ip=new JLabel("SMTP服务器地址");
lsmtp_port=new JLabel("SMTP服务器端口号");
limap_ip=new JLabel("IMAP服务器地址");
limap_port=new JLabel("IMAP服务器端口号");
lsmtp_ip1=new JLabel("SMTP服务器地址");
lsmtp_port1=new JLabel("SMTP服务器端口号");
lemail=new JLabel("邮箱地址");
lpwd=new JLabel("口令");
//输入框
pop3_ip=new JTextField(20);
pop3_port=new JTextField(10);
smtp_ip=new JTextField(20);
smtp_port=new JTextField(10);
imap_ip=new JTextField(20);
imap_port=new JTextField(10);
smtp_ip1=new JTextField(20);
smtp_port1=new JTextField(10);
email=new JTextField();
pwd=new JTextField();
blank=new JTextField(80);
blank.setVisible(false);
//单选
jradio1=new JRadioButton("POP3/SMTP服务器");
jradio2=new JRadioButton("IMAP/SMTP服务器");
ButtonGroup group=new ButtonGroup();
//把单选按钮添加到按钮组中,这样只能选组中的一个按钮,真正实现单选
group.add(jradio1);
group.add(jradio2);
jradio1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
jradio2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
//按钮
send=new JButton("登录并发送");
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
receive=new JButton("登录并接收");
receive.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
concel=new JButton("取消");
concel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
p1.add(setting,BorderLayout.NORTH);
//p1.add(setting);
p2.add(jradio1);
p2.add(new JTextField(80));
p2.add(lpop3_ip);
p2.add(pop3_ip);
p2.add(lpop3_port);
p2.add(pop3_port);
p2.add(lsmtp_ip);
p2.add(smtp_ip);
p2.add(lsmtp_port);
p2.add(smtp_port);
p1.add(p2,BorderLayout.CENTER);
this.add(p1,BorderLayout.NORTH);
this.setSize(680, 800);
this.setLocation(200, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String args[]) {
new login();
}
}
MailClient.java
import javax.mail.*;
import javax.mail.internet.*;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.security.Security;
import java.util.Properties;
public class MailClient extends JFrame {
private String host;
private String username;
private String password;
private Session session;
private Store store;
private DefaultListModel<String> mailListModel;
//关于读取邮件
Folder inbox;
Message[] messages;
int messageCount;
//
//用表格展示
//
private JList<String> mailList;
private JTextArea contentArea;
private JButton detailButton;
public MailClient() {
// 设置邮件服务器地址、用户名和密码
host = "pop.qq.com";
username = "9999@qq.com"; //替换
password = " vbbbbbbbb "; //替换
// 设置邮件客户端界面
setTitle("Mail Client");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setLocation(600,200);
setLayout(new BorderLayout());
// 创建邮件列表和内容显示区域
mailListModel = new DefaultListModel<>();
mailList = new JList<>(mailListModel);
JScrollPane mailListScrollPane = new JScrollPane(mailList);
contentArea = new JTextArea();
// 创建查看详情按钮
detailButton = new JButton("查看详情");
detailButton.setEnabled(false);
// 将组件添加到界面中
add(mailListScrollPane, BorderLayout.WEST);
add(new JScrollPane(contentArea), BorderLayout.CENTER);
add(detailButton, BorderLayout.SOUTH);
// 监听邮件列表选中事件
mailList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int selectedIndex = mailList.getSelectedIndex();
if (selectedIndex >= 0) {
detailButton.setEnabled(true);
}
}
}
});
// 监听查看详情按钮点击事件
detailButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selectedIndex = mailList.getSelectedIndex();
System.out.println("选中的序号是"+selectedIndex);
if (selectedIndex >= 0) {
try {
// 通过JavaMail API获取邮件的详细信息
//Message message = store.getFolder("INBOX").getMessage(selectedIndex + 1);
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
Message message = messages[messageCount - selectedIndex-1];
String subject = message.getSubject();
String sender = ((InternetAddress) message.getFrom()[0]).getAddress();
//String content = message.getContent().toString();
String content = "";
// 在新窗口中显示邮件的详细信息
JFrame detailFrame = new JFrame("邮件详情");
detailFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
detailFrame.setSize(600, 300);
detailFrame.setLocation(680,250);
JTextArea detailArea = new JTextArea();
detailArea.setEditable(false);
//用个循环来添加内容
if (message.isMimeType("multipart/*")) {
Multipart mp = (Multipart) message.getContent();
System.out.println("所包含的MimeBodyPart对象的数目:"+mp.getCount());
//循环每个MimeBodyPart,获取里面的内容//有点重复代码
for (int i = 0; i < mp.getCount(); i++) {
BodyPart bodyPart = mp.getBodyPart(i);
String disposition = bodyPart.getDisposition();
//如果是附件
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
String filename1 = myDecoder(bodyPart.getFileName());
content+="附件内容:"+filename1+"\n";
}else
//正文内容
{
content+="正文内容:"+bodyPart.getContent().toString()+"\n";
}
}
}else
//如果不是multipart,只有一段文字
{
content+="正文内容:"+message.getContent().toString();
content+="附件内容:";
}
detailArea.setText("发件人: " + sender
+"\n主题: " + subject
+"\n内容:\n"+content);
JButton downloadButton = new JButton("下载附件");
downloadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
// 检查邮件中是否包含附件
if (message.isMimeType("multipart/*")) {
Multipart mp = (Multipart) message.getContent();
System.out.println("所包含的MimeBodyPart对象的数目:"+mp.getCount());
for (int i = 0; i < mp.getCount(); i++) {
BodyPart bodyPart = mp.getBodyPart(i);
String disposition = bodyPart.getDisposition();
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
String filename1 = myDecoder(bodyPart.getFileName());
//getFileName():Get the filename associated with this body part.
String realname = saveFile(filename1,bodyPart.getInputStream()); //getInputStream():Return a decoded input stream for this body part's "content".
detailArea.append("\nthe attachment is "+filename1+". It has been saved as \""+realname+"\"");
//System.out.println("the attachment is "+filename1+". It has been saved as \""+realname+"\"");
//
/*
InputStream is = bodyPart.getInputStream();
File file = new File(bodyPart.getFileName());
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buf)) != -1) {
fos.write(buf, 0, bytesRead);
}
fos.close();
*/
JOptionPane.showMessageDialog(detailFrame, "附件下载成功!");
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(detailFrame, "附件下载失败!");
}
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(downloadButton);
detailFrame.getContentPane().add(new JScrollPane(detailArea), BorderLayout.CENTER);
detailFrame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
detailFrame.setVisible(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
// 连接到邮件服务器并读取邮件列表
try {
Properties props = new Properties();
// props.put("mail.imap.host", host);
// props.put("mail.imap.port", "993");
// props.put("mail.imap.ssl.enable", "true");
//qq的属性
props.put("mail.store.protocol", "pop3");
props.put("mail.pop3.host", host);
props.put("mail.pop3.port", "995");
//添加安全认证
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());//设置安全提供者
props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.pop3.socketFactory.fallback", "false");
props.put("mail.pop3.socketFactory.port", "995");
props.put("mail.pop3.starttls.enable", "true");
//
session = Session.getDefaultInstance(props);
//这个地方不能加协议,不然和上面的pop3对不起来,而且只能查看由imap协议发送来的邮件,
//这就是为什么用下面这个会出现很久之前的邮件
//store = session.getStore("imaps");
store = session.getStore();
store.connect(host, username, password);
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
//获取邮件
messages = inbox.getMessages();
//获取邮件数量
messageCount = inbox.getMessageCount();
System.out.println("邮件数量:"+messageCount);
//设置循环变量
int disp_num = messageCount;
if (disp_num>5){
disp_num = 5;
}
//下面的循环就是取最新的五封邮件
//mailListModel.addElement("序号"+"发件人"+"主题"+"附件");
int num=1;
for(int i = messageCount -1; i>messageCount - disp_num-1 ; i--){
System.out.println((messageCount-i)+":\t from<"+ myDecoder(messages[i].getFrom()[0].toString())
+">, Subject:"+myDecoder(messages[i].getSubject())+"\n");
Message message = messages[i];
String from=myDecoder(messages[i].getFrom()[0].toString());
String subject = message.getSubject();
//给附件赋值
String attachment="";
if(messages[i].isMimeType("multipart/*")){
Multipart mp = (Multipart)(messages[i].getContent());
int n = mp.getCount(); //返回所包含的MimeBodyPart对象的数目
for(int j =0; j<n ;j++){
Part part = mp.getBodyPart(j);
//如果存在附件!!
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
attachment = myDecoder(part.getFileName());
System.out.println("附件:"+attachment);
}
}
}
mailListModel.addElement("序号:"+num+" --- "+"发件人:"+from+" --- "+"主题:"+subject + " --- " +"附件:"+ attachment);
num++;
}
/*for (int i = 0; i < messageCount; i++) {
Message message = inbox.getMessage(i + 1);
String subject = message.getSubject();
String sender = ((InternetAddress) message.getFrom()[0]).getAddress();
mailListModel.addElement(subject + " - " + sender);
}*/
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "无法连接到邮件服务器或读取邮件列表失败!");
}
}
String myDecoder(String str){
String result = str;
try {
result = MimeUtility.decodeText(str);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
String saveFile(String filename, InputStream input){
File file = new File(filename);
/*String mainfilename = filename;
String extfilename = "";
int index = filename.indexOf(".");
if(index!=-1){
mainfilename = filename.substring(0, index);
extfilename = filename.substring(index);
}
System.out.println(index);
for (int i =1;file.exists();i++){
file = new File(mainfilename+"("+i+")"+extfilename);
}*/
try {
BufferedInputStream fin = new BufferedInputStream(input);
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(file));
try {
int value = fin.read();
while(value != -1){
fos.write(value);
value = fin.read();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(fos != null){
fos.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return file.getName();
}
public static void main(String[] args) {
//下面这个就是等到获取到消息之后在调用
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MailClient().setVisible(true);
}
});
}
}
1. 描述一下因特网电子邮件系统的组成。
(1) 用户代理
(2) 邮件服务器
(3) 简单邮件传输协议(smtp)
2. 常用的发送邮件和接收邮件协议有哪些?
SMTP、POP3、IMAP
3. 利用javamail编制电子邮件客户端程序的主要步骤是什么?
(1)发送端:设置mail.host属性,指向本地服务器
利用Session.getInstance()启动邮件会话
创建MimeMessage邮件对象
设置收件人、发件人、邮件主题、邮件内容
利用Transport.send()方法发送邮件
(2)接收端:创建store对象并连接服务器
创建forder对象,并打开文件夹
获取收件箱中的邮件
获取收件箱中邮件的数量
显示邮件内容