javamail实现腾讯邮箱(企业邮箱,qq邮箱)发送邮件(多收件人多附件)

Maven 依赖

        <!-- javaemail -->
        <javaemail.version>1.4.5</javaemail.version>
        <mail.version>1.4.1</mail.version>

        <!-- javamail 发送邮件-->
        <dependency>
        <groupId>javamail</groupId>
            <artifactId>javamail</artifactId>
            <version>${javaemail.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>${mail.version}</version>
        </dependency>

email.properties

     #test emailwithfile
     mail.smtp.host=smtp.exmail.qq.com
     mail.smtp.port=465
     mail.smtp.protocol=smtp
     mail.sender.username=你的邮箱登录名
     mail.sender.password=你的邮箱密码

代码实现

  1. 未解决的问题:
    当发送多个人多邮件时,第一次发送采用SSL加密,但是第二次以后都不是采用SSL加密方式验证;
    我只创建了一个session,查看源代码发现,难道是每次发送邮件都会调用下面方法,session在第一次就消耗了?
 Session s = (msg.session != null) ? msg.session Session.getDefaultInstance(System.getProperties(), null);
  1. 代码改进
    查看源代码 如果不需要SSL加密可以采用transport.sendMessage(msg, addresses),因为Transport.send(message,Address[] address)调用了 transport.sendMessage(msg, addresses);
 Session s = (msg.session != null) ? msg.session : Session.getDefaultInstance(System.getProperties(), null);
    Transport transport;
    if (dsize == 1) {
      transport = s.getTransport(addresses[0]);
      try {
        transport.connect();
        transport.sendMessage(msg, addresses);
      } finally {
        transport.close();
      }
      return;
    }

2.采用Address[]会比采用InternetAddress[]接收收件人发送多收件人邮件时更快,查看源代码发现
因为InternetAddress是继承与Address,
测试代码:同时向两个收件人发送两个附件信息:

long time1=System.currentTimeMillis();
        boolean  isSend=    sendEmail.sendEmail(subject, nickName, sendHtml, receiveUser, filePath);
        long time2=System.currentTimeMillis();
        System.err.println("sendEmail spend time:"+(time2-time1));
对比结果采用Address[]:
250 Ok: queued as 
QUIT
221 Bye
send success!
sendEmail spend time:1520
对比结果采用InternetAddress[]:
250 Ok: queued as 
QUIT
221 Bye
send success!
sendEmail spend time:1210
3.经过实验发现当采用SSL验证时,邮件端口号为465,当不采用SSL验证时,端口号为25;
采用SSL验证:
DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.exmail.qq.com", port 465, isSSL true
220 smtp.qq.com Esmtp QQ Mail Server
DEBUG SMTP: connected to host "smtp.exmail.qq.com", port: 465
不采用SSL验证:
=09DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.m=
ail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.exmail.qq.com", port 25, isSSL =
false
220 smtp.qq.com Esmtp QQ Mail Server
DEBUG SMTP: connected to host "smtp.exmail.qq.com", port: 25

附上源代码

package com.meyacom.tool;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
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.PasswordAuthentication;
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 org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.sun.mail.util.MailSSLSocketFactory;

/**
 * Title: FileEmaliUtil
 * <p>
 * Description:发送带附件的邮件(多收件人多附件)
 * <p>
 * Copyright: Copyright (c) 2016
 * <p>
 * Company:
 * <p>
 * 
 * @author zhoulin.zhu
 *         <p>
 *         2016年8月25日
 */
public class SendEmaliUtil {
    protected Logger logger = Logger.getLogger(this.getClass());


    private MimeMessage message;

    private String mailHost = "";
    private String mailPort = "";
    private String mailProtocol = "";
    private String sender_username = "";
    private String sender_password = "";

    private Properties properties = new Properties();

    /*
     * 初始化方法
     */
    public SendEmaliUtil(boolean debug) {
        InputStream in = ClassLoader
                .getSystemResourceAsStream("email.properties");
        try {
            properties.load(in);
            this.mailHost = properties.getProperty("mail.smtp.host");
            this.mailPort = properties.getProperty("mail.smtp.port");
            this.mailProtocol = properties.getProperty("mail.smtp.protocol");
            this.sender_username = properties
                    .getProperty("mail.sender.username");
            this.sender_password = properties
                    .getProperty("mail.sender.password");
        } catch (IOException e) {
            System.out.println("读取默认参数文件异常,请重试!");

        }

    }

    /**
     * 用户名密码验证,需要实现抽象类Authenticator的抽象方法PasswordAuthentication,
     * SMTP验证类(内部类),继承javax.mail.Authenticator
     */
    class MyAuthenricator extends Authenticator {
        String username = null;
        String password = null;

        public MyAuthenricator(String username, String password) {
            this.username = username;
            this.password = password;
        }

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    }

    /**
     * 指定发送邮件
     * 
     * @param subject
     *            邮件主题
     * @param sendHtml
     *            邮件内容
     * @param sender_nickName
     *            发送邮件人地址
     * @param receiveUser
     *            收件人列表,以","分割
     * @param filePath
     *            附件列表
     */
    public boolean sendEmail(String subject, String sender_nickName,
            String sendHtml, String receiveUser, List<String> filePath) {
        Properties prop = new Properties();
        // 协议
        prop.setProperty("mail.transport.protocol", mailProtocol);
        // 服务器
        prop.setProperty("mail.smtp.host", mailHost);
        // 端口
        prop.setProperty("mail.smtp.port", mailPort);
        // 使用smtp身份验证
        prop.setProperty("mail.smtp.auth", "true");
        // 使用SSL,企业邮箱必需!
        // 开启安全协议
        MailSSLSocketFactory sf = null;
        try {
            sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
        } catch (GeneralSecurityException e1) {
            System.out.println("开启SSL加密异常!");           
            e1.printStackTrace();
            return false;
        }
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);
        Session session = Session.getDefaultInstance(prop, new MyAuthenricator(
                sender_username, sender_password));
        session.setDebug(true);// 开启DEBUG模式,在控制台中或日志中有日志信息显示,也就是可以从控制台中看一下服务器的响应信息;
        message = new MimeMessage(session);
        try {
            InternetAddress from;

            if (StringUtils.isNotBlank(sender_nickName)) {
                // 发件人,昵称
                from = new InternetAddress(
                        MimeUtility.encodeWord(sender_nickName) + "<"
                                + sender_username + ">");
            } else {
                // 发件人
                from = new InternetAddress(
                        MimeUtility.encodeWord(sender_nickName));
            }
            message.setFrom(from);

            // 创建收件人列表
            if (StringUtils.isNotBlank(receiveUser)) {
                // 替换收件人的分隔符(防止中文下产生无法分割成收件人数组的','替换成',')
                String rescivers = receiveUser.replaceAll(",", ",");
                String[] arr = rescivers.split(",");
                if (arr.length > 0) {
                    // 收件人 
                    //采用Address【】比InternetAddress发送邮件速度更快 因为InternetAddress是继承与Address,
                    Address[] address=new Address[arr.length];
                    //InternetAddress[] address = new InternetAddress[arr.length];
                    for (int i = 0; i < arr.length; i++) {
                        address[i] = new InternetAddress(arr[i]);
                    }
                    message.setRecipients(Message.RecipientType.TO, address);

                    // 发送时间
                    message.setSentDate(new Date());

                    // 邮件主题
                    message.setSubject(subject);

                    // 向multipart对象中添加邮件的各个部分内容,包括文本内容和附件
                    Multipart multipart = new MimeMultipart();

                    // 添加邮件正文
                    BodyPart contentPart = new MimeBodyPart();
                    contentPart.setContent(sendHtml, "text/html;charset=UTF-8");

                    multipart.addBodyPart(contentPart);

                    // 附件操作
                    if (filePath != null && filePath.size() > 0) {
                        for (String filename : filePath) {
                            BodyPart attachmentBodyPart = new MimeBodyPart();
                            DataSource source = new FileDataSource(filename);
                            attachmentBodyPart.setDataHandler(new DataHandler(
                                    source));
                            // MimeUtility.encodeWord可以避免文件名乱码
                            attachmentBodyPart.setFileName(MimeUtility
                                    .encodeWord(source.getName()));
                            multipart.addBodyPart(attachmentBodyPart);
                        }                       
                        // 移走集合中的所有元素
                        filePath.clear();
                    }
                    // 将multipart对象放到message中
                    message.setContent(multipart);

                    // 保存邮件
                    message.saveChanges();
                    // 不采用ssl加密发送
                    // transport = session.getTransport("smtp");
                    // smtp验证,就是你用来发邮件的邮箱用户名密码
                    // transport.connect(mailHost, sender_username,
                    // sender_password);
                    // 发送
                    // transport.sendMessage(message,
                    // message.getAllRecipients());

                    // 发送                   
                    Transport.send(message,address);
                    System.out.println("send success!");
                }
            }

            return true;
        } catch (Exception e) {
            System.out.println("message异常!");
            e.printStackTrace();
            return false;
        }
    }

    public static void main(String[] args) {

        String subject = "测试";
        String nickName = "风中思絮";
        String sendHtml = "<p class='color:red'>由于下雨,周末不加班!</p>";

        String receiveUser = "xxx@meyacom.com,XXX@qq.com";
//      String receiveUser = "xxx@qq.com";

        List<String> filePath = new ArrayList();
//      filePath.add("D:\\JAVAStudy\\bpm学习\\SVN地址.txt");
        filePath.add("D:\\JAVAStudy\\学习进度\\学习目标及目标.txt");
//      filePath.add("D:\\JAVAStudy\\bpm学习\\BPM配置文档(1).docx");
        filePath.add("D:\\JAVAStudy\\bpm学习\\OA\\任务分配.png");
//      filePath.add("D:\\JAVAStudy\\微信支付.rar");

        SendEmaliUtil sendEmail = new SendEmaliUtil(true);
        long time1=System.currentTimeMillis();
        boolean  isSend=    sendEmail.sendEmail(subject, nickName, sendHtml, receiveUser, filePath);
        long time2=System.currentTimeMillis();
        System.err.println("sendEmail spend time:"+(time2-time1));
    }
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风中思絮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值