JavaMail

Posted OverZeal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaMail相关的知识,希望对你有一定的参考价值。

在B/S模式的应用中,收发邮件是一件比较常见的功能,在Java Web中可以使用JavaMail,在使用Java发送邮件,必须知道发送方和收件方的邮箱地址,另外,发送发还要知道自己的邮箱地址,但是无需知道收件方的密码

了解一下基础知识

邮件传输

在Internet上,邮件是以SMTP(简单邮件传输协议)来传输的,所以,发送方需要知道自己邮件服务商的SMTP服务器地址。163的SMTP服务器地址是smtp.163.com,腾讯的是smtp.qq.com,其他的可以在其网站上查询

邮件收取

在Internet上,邮件是以POP(邮局协议,目前使用的是第3个版本,也称POP3)来收取的。如果是使用Java收邮件,就需要知道POP服务器地址,163的是:pop3.163.com ,而腾讯的是:pop3.qq.com

也就是说只是单纯发邮件,只需要知道发送方的SMTP地址,如果要收邮件才须知道POP服务器

邮件表达

邮件是根据MIME(多用途因特网邮件扩展)来标准表达的,它对传输内容的信息,附件及其他内容定义了格式

准备工作

要想使用JavaMail需要在下载Javamail开发包(javax.mail.jar),和JavaBeans Activation Framework(JAF)(解压后使用activation.jar),JAF是用来处理带附件的邮件的,将在这两个jar包放在WEB-INF/lib目录下就行了

javax.mail.Session类是用来创建邮件对象,实现邮件对象中数据的封装并可以指定一些属性

javax.mail.Transport类用于发送邮箱,可以根据Session类对象的getTransport()方法生成

javax.mail.internet.InternetAddress用于封装邮箱地址

javax.mail.internet.MineMessage是邮件的消息类

发送简单的内容

这里我是用Jsp来写的,以后可以灵活改变,值得注意的是包不要导错了,建议使用javax.mail.*和javax.mail.internet.*(要导入这两个包中的内容)

<%@page import="javax.mail.*"%>
<%@page import="javax.mail.internet.*"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>发送邮件</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <%
    String to_mail="[email protected]";       //接受方地址(灵活改变)
    String title="这是一封邮件";                //邮件标题
    String content="<strong>你好,欢迎注册本购物网站</strong>";     //邮件内容
    
    /*1.创建邮箱的连接会话 javax.mail.Session*/
    Properties prop=new Properties();
    prop.put("mail.smtp.auth", "true");            //指定登录时必须验证
    Session s=Session.getInstance(prop);
    
    /*2.创建邮件:根据Session建立*/
    MimeMessage message=new MimeMessage(s);
    //设置邮件发送方(灵活改变)
    message.setFrom(new InternetAddress("[email protected]"));
    //设置邮箱的接收方
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to_mail));
    
    //设置邮箱标题
    message.setSubject(title);
    //设置邮箱内容
    message.setContent(content,"text/plain;charset=utf-8");
    message.setSentDate(new Date());               //设置邮箱发送时间
    message.saveChanges();                         //保存发送
    
    /*3.连接到发送方的smtp服务器,用javax.mail.Transport来传输*/
    Transport tran=s.getTransport("smtp");
    //发送方smtp服务器地址,账号,密码(灵活改变)
    tran.connect("smtp.163.com", "18337953723", "return0;");
    
    /*4.发邮件*/
    tran.sendMessage(message, message.getAllRecipients());
    tran.close();
    out.print("发送成功");
     %>
  </body>
</html>

发送带HTML的邮件

使用带HTML格式的邮件可以使内容更丰富更具表现力。不过要使用MimeMultipart对象来存放BodyPart,即HTML文件内容,而且设置内容时要设置对象格式:text/html;charset=utf-8,在发送简单内容时使用的是text/plain;charset=utf-8

<%@page import="javax.mail.internet.*"%>
<%@page import="javax.mail.*"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>发送带HTMl的邮件</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <%
    String to_mail="[email protected]";       //接受方地址(灵活改变)
    String title="这是一封邮件";                //邮件标题
    String content="<strong>你好</strong>,<em>欢迎注册本购物网站</em>";     //邮件内容(带HTML)
    
    /*1.创建邮箱的连接会话 javax.mail.Session*/
    Properties prop=new Properties();
    prop.put("mail.smtp.auth", "true");            //指定登录时必须验证
    Session s=Session.getInstance(prop);
    
    /*2.创建邮件:根据Session建立*/
    MimeMessage message=new MimeMessage(s);
    //设置邮件发送方(灵活改变)
    message.setFrom(new InternetAddress("[email protected]"));
    //设置邮箱的接收方
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to_mail));
    
    //设置邮箱标题
    message.setSubject(title);
    //给消息对象设置内容
    //新建一个存放信件内容的BodyPart对象
    BodyPart mdp=new MimeBodyPart();
    //给BodyPart对象设置内容和编码格式
    mdp.setContent(content,"text/html;charset=utf-8");
    //新建一个MimeMultipart对象来存放BodyPart对象
    Multipart mm=new MimeMultipart();
    //将Bodypart加入到MimeMultipart对象中(可以加入多个)
    mm.addBodyPart(mdp);
    //把mm作为消息对象的内容
    message.setContent(mm);
    message.setSentDate(new Date());               //设置邮箱发送时间
    message.saveChanges();                             //保存发送
    
    /*3.连接到发送方的smtp服务器,用javax.mail.Transport来传输*/
    Transport tran=s.getTransport("smtp");
    //发送方SMTP服务器,账号,密码
    tran.connect("smtp.163.com", "18337953723", "return0;");
    
    /*4.发邮件*/
    tran.sendMessage(message, message.getAllRecipients());
    tran.close();
    out.print("发送成功");
     %>
  </body>
</html>

发送带附件的邮件

发送带附件的邮件就需要使用Javax.activation包(就是JAF中的),在这里发送方将c:/balloons.jpg发送出去

<%@page import="javax.activation.DataHandler"%>
<%@page import="javax.activation.FileDataSource"%>
<%@page import="javax.mail.internet.*"%>
<%@page import="javax.mail.*"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>发送带附件的邮件</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <%
    String to_mail="[email protected]";       //接受方地址(灵活改变)
    String title="这是一封带附件邮件";                //邮件标题
    String content="<strong>你好</strong>,<em>欢迎注册本购物网站</em>";     //邮件内容(带HTML)
    String path1="c:/balloons.jpg";                     //选择的附件(灵活改变)
    
    /*1.创建邮箱的连接会话 javax.mail.Session*/
    Properties prop=new Properties();
    prop.put("mail.smtp.auth", "true");            //指定登录时必须验证
    Session s=Session.getInstance(prop);
    
    /*2.创建邮件:根据Session建立*/
    MimeMessage message=new MimeMessage(s);
    //设置邮件发送方(灵活改变)
    message.setFrom(new InternetAddress("[email protected]"));
    //设置邮箱的接收方
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to_mail));
    
    //设置邮箱标题
    message.setSubject(title);
    //设置邮件内容是包含附件的,附件用MimeMultipart来承载
    MimeMultipart mm=new MimeMultipart();
    message.setContent(mm);                       //将mm设置为内容
    MimeBodyPart mbp=new MimeBodyPart();
    //向mbp内添加文件
    FileDataSource fbs=new FileDataSource(path1);
    DataHandler dh=new DataHandler(fbs);
    mbp.setDataHandler(dh);
    mbp.setFileName(MimeUtility.encodeText("图片.jpg"));     //传到对方显示的文件名,使用MimeUtility工具类手工编码
    
    //添加附件
    mm.addBodyPart(mbp);
    
    
    BodyPart mdp=new MimeBodyPart();
    //给BodyPart对象设置内容和编码格式
    mdp.setContent(content,"text/html;charset=utf-8");
    mm.addBodyPart(mdp);

    message.setSentDate(new Date());               //设置邮箱发送时间
    message.saveChanges();                         //保存发送   

    /*3.连接到发送方的smtp服务器,用javax.mail.Transport来传输*/
    Transport tran=s.getTransport("smtp");
    //发送行SMTP服务器,账号,密码(灵活改变)
    tran.connect("smtp.163.com", "18337953723", "return0;");
    
    /*4.发邮件*/
    tran.sendMessage(message, message.getAllRecipients());
    tran.close();
    out.print("发送成功");
     %>
  </body>
</html>

值得注意的是:发送带附件使用的是MimeBodyPart类,而发送带HTML格式内容要使用BodyPart类,这两个类都可以使用new MimeBodyPart()new出来。还有一个就是附件中文名乱码问题

 mbp.setFileName(MimeUtility.encodeText("图片.jpg"));     //传到对方显示的文件名,使用MimeUtility工具类手工编码

如果不进行编码,接收方的附件名就是乱码

这是因为MIME规范要求附件标题必须是US-ASCII字符,同时又不允许对参数进行编码,因此JavaMail API中并不会主动对含有非ASCII字符的文件名进行编码处理。但是,JavaMail同时也提供了工具类使得用户可以方便的对类似情况进行手工处理:
对文件名进行编码:
mbp.setFileName(MimeUtility.encodeText(filename));
对文件名进行解码:
String filename = MimeUtility.decodeText(part.getFileName());

读取邮件

通过JavaMail来读取邮件服务器的邮件,实际使用并不多

javax.mail.Store类用于读取邮件,可由Session类对象的getStore()方法生成

javax.mail.Folder类用于保存某文件夹中的所有邮件,常用方法是getMessage()用于返回文件夹下所有邮件,是以Message数组返回

<%@page import="javax.mail.Message"%>
<%@page import="javax.mail.Folder"%>
<%@page import="javax.mail.Store"%>
<%@page import="javax.mail.Session"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>读取邮件</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>
  
  <body>
    <%
    //将邮箱的邮件数显示,需要知道密码
    /*1.创建会话*/
    Session s=Session.getInstance(System.getProperties(),null);      //得到系统默认属性
    /*邮箱传输使用smtp,接受使用pop3*/
    
    /*2.连接到pop服务器,获取邮件*/
    Store store=s.getStore("pop3");
    //需要获得邮件POP服务器地址,邮箱地址,密码(灵活改变)
    store.connect("pop3.163.com","[email protected]","return0;");
    //得到收件箱里面的邮件,INBOX是关键字,还有其他关键字(灵活改变)
    Folder folder=store.getFolder("INBOX");
    folder.open(Folder.READ_WRITE);           //可以显示,可以删除
    
    /*3.显示邮件的内容*/
    Message[] megs=folder.getMessages();
    out.print("邮件共有"+megs.length+"封<HR>");
    for(int i=0;i<megs.length;i++){
      Message meg=megs[i];
      out.print(meg.getSubject()+"<BR>");
      out.print("<HR>");
    }
    store.close();
     %>
  </body>
</html>

 

以上是关于JavaMail的主要内容,如果未能解决你的问题,请参考以下文章

Android Java使用JavaMail API发送和接收邮件的代码示例

JavaMail实现邮箱验证码

javamail发邮件

JavaMail 内容传输编码问题

JavaMail实现带附件的收发邮件

使用 javamail 使用 Swing 查看电子邮件