JavaMail发送邮件和附件(源码)-程序员宅基地

技术标签: 邮件服务器  string  session  javamail  javaEE  user  properties  

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lenolong/article/details/3958201

智能推荐

Linux下升级MySQL版本_linux mysql升级后版本不变-程序员宅基地

文章浏览阅读9.7k次。升级MySQL的方法其实就是将原来的安装的MySQL彻底的卸载,然后在安装新的版本。卸载MySQL:1.先查看安装的MySQL的软件,命令如下:rpm -qa|grep -i mysql可以看到如下图的所示显示安装了 mysql-community-libs-5.7.22-1.el7.x86_64mysql-community-common-5.7.22-1.e..._linux mysql升级后版本不变

puppeteer-不需重构,无痛加强vue单页面应用的SEO,提升百度收录排名_puppeteer seo-程序员宅基地

文章浏览阅读1.6k次,点赞2次,收藏5次。puppeteer-不需重构,无痛加强vue单页面应用的SEO,提升百度收录排名_puppeteer seo

《网络空间安全概论》课程笔记及心得(3)_学习巜网络空间安全概论》收获-程序员宅基地

文章浏览阅读3k次。《网络空间安全概论》课程笔记及心得(3)第五章 网络攻防技术1.信息收集技术·网络踩点( Footprinting)了解攻击目标的隐私信息、网络环境和信息安全状况。根据踩点结果,攻击者寻找出攻击目标可能存在的薄弱环节。在入侵一个目标系统之前,必须了解目标系统可能存在的:管理上的安全缺陷和漏洞、网络协议安全缺陷与漏洞、系统安全缺陷与漏洞;在入侵实施过程中,还需要进一步掌握:目标..._学习巜网络空间安全概论》收获

Linux下Eclipse使用NDK开发Android应用_ndk 编写安卓应用 eclipse-程序员宅基地

文章浏览阅读1.3k次。Google提供的Android SDK 已经能够满足绝大多数场景下的Android_ndk 编写安卓应用 eclipse

二阶sql注入里面隐藏了一些东西-程序员宅基地

文章浏览阅读433次。Summary : 总结: Everyone knows what is SQL Injection, but just to give you a brief about SQL Injection, it is a code injection technique that might destroy your database. It usually occurs when you ask...

swift 中隐藏导航栏_在Swift中隐藏和显示导航栏和标签栏-程序员宅基地

文章浏览阅读3k次。swift 中隐藏导航栏Since everyone wants their app to look neat, attractive, and fascinating, non-standard UI elements and animations are becoming very popular. HidingNavigationBar is such a framework. It hel...

随便推点

智慧地球(iEarth): 服务可持续发展的跨学科框架 | NSR观点-程序员宅基地

文章浏览阅读294次。联合国可持续发展目标(SDGs)关系着人类的未来生存和发展问题,为了更好地实现可持续发展目标,香港大学宫鹏教授研究组和中国科学院郭华东院士研究组联合提出了智慧地球(iEarth)的跨学科框架。该项研究以“iEarth: an interdisciplinary framework in the era ofbig data and AI for sustainable development”为...

基于JavaWeb实现ATM机模拟取款系统实战(用户端操作)_atm机用java实现怎么从数据库里查到余额-程序员宅基地

文章浏览阅读292次。这篇文章主要介绍项目用户端的操作,包括查看余额,存钱,取钱,转账,和退卡操作,以及分页设置_atm机用java实现怎么从数据库里查到余额

备忘录形成html乱码,浏览器icloud网页版备忘录乱码不能显示中文汉字-企业网站设计之中的字体坑...-程序员宅基地

文章浏览阅读2.2k次。iphone备忘录是一个很好用的功能,能方便我们记录一些临时的想法和内容,但是这些内容怎么复制到电脑呢,网页版icloud是一个很好的选择。但是最近icloud网页版却出现了兼容问题不能正常的显示中文。如下图所示选中的部分其实是有文字的,但是在网页上却看不到中文内容只有英文可以正常显示。这其实是网页字体带来的问题。解决办法一:1、打开浏览器,并打开开发人员工具(试用系统自带的edge,按f12);..._网页版的icloud备忘录不显示符号

SSM + jsp整合shiro_ssm+jsp整合shiro-程序员宅基地

文章浏览阅读371次。1.首先整合SSM框架,起码项目要能跑起来以前整合好的ssm框架springmvc-config.xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.spr_ssm+jsp整合shiro

《华为C&C++语言安全规范》笔记_华为 c&c++ 语言安全编程规范-程序员宅基地

文章浏览阅读7.5k次,点赞9次,收藏59次。《华为C&C++语言安全规范》笔记通过阅读《华为C&C++语言安全规范》1,我了解到了我在编程中很多缺失的部分。现在记录下几个要点:规则1.1.4:严禁对指针变量进行sizeof操作编码人员往往由于粗心,将指针当做数组进行sizeof操作,导致实际的执行结果与预期不符。 下面的代码,buffer和path分别是指针和数组,编码人员想对这2个内存进行清0操作,但由于编码人员的疏忽,第5行代码,将内存大小误写成了sizeof,与预期不符。如果要判断当前的指针类型大小,请使用sizeof_华为 c&c++ 语言安全编程规范

织梦html5博客模板,HTML5响应式清爽博客文章织梦模板 v1.0-程序员宅基地

文章浏览阅读260次。HTML5响应式清爽博客文章织梦模板简介HTML5响应式清爽博客文章织梦模板是一个自适应手机端和PC端的最新版织梦V5.7为内核的网站模板,软件兼容主流浏览器,模板包含安装说明,并包含测试数据。dedecms最新版内核开发,原创设计、手工书写DIV+CSS,完美兼容IE7+、Firefox、Chrome、360浏览器等;主流浏览器;页面简洁简单,容易管理,DEDE内核都可以使用;附带测试数据!模板..._html5个人博客新闻资讯自适应织梦模板

推荐文章

热门文章

相关标签