当前位置: 首页 > article >正文

IntelliJ+SpringBoot项目实战(25)--使用JavaMail发送邮件

       一、概述

        在SpringBoot中实现邮件发送,可以使用传统模式以及SpringBoot自带的springboot-starter-mail。本文暂时介绍传统的发邮件模式。基于springboot-starter-mail发送邮件后面再介绍。

       关于邮件发送的测试,有几点一定要注意:

     (1)切记现在很多邮箱服务器不支持在非公网IP的环境下发送邮件,比如在自己的开发机器上测试邮件发送,经常连不到邮件发送服务器(465)端口。

     (2)以前的SMTP端口一般都是25,且不需要SSL。现在的邮件服务器大部分的SMTP端口默认是465,而且只能使用SSL发送。有的邮件服务器的SMTP端口比较隐蔽,需要咨询下服务商。

     (3)邮件发送参数的设置,如果设置不当可能会导致无法发送邮件,下面是发邮件常用的设置:

        System.setProperty("java.net.preferIPv4Stack", "true");  
        props.put("mail.smtp.auth","true");      
        //使用JSSE的SSL socketfactory来取代默认的socketfactory
        props.put("mail.smtp.socketFactory.class", SSL_FACTORY);  
        // 只处理SSL的连接,对于非SSL的连接不做处理
        props.put("mail.smtp.socketFactory.fallback", "false");  
        props.put("mail.smtp.socketFactory.port", port);
        // props.put("mail.store.protocol" , protocol);
        props.put("mail.smtp.starttls.enable", true);
        props.put("mail.smtp.ssl.enable", true);//这句漏掉了导致SSL发送老提示连不上
        props.put("mail.transport.protocol", "smtps"); // 启用smtps方式

    二、实现带附件的邮件发送

        在SpringBoot中引入邮件依赖,在openjweb-core中加入下面的依赖:

        

        <!--mail-->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.5.4</version>
        </dependency>

        然后实现一个SmtpAuth,继承javax.mail.Authenticator:

package org.openjweb.core.mail;

public class SmtpAuth extends javax.mail.Authenticator {
    private String username,password;

    public SmtpAuth(String username,String password){
        this.username = username;
        this.password = password;
    }
    protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
        return new javax.mail.PasswordAuthentication(username,password);
    }
}

        再实现一个Mail类,使用此类发送带附件的邮件或者不带附件的邮件:

package org.openjweb.core.mail;

import org.openjweb.common.util.StringUtil;
import java.util.* ;
import javax.mail.* ;
import javax.mail.internet.* ;
import javax.activation.* ;

public class Mail {
    //定义发件人、收件人、SMTP服务器、用户名、密码、主题、内容等
    private String displayName;
    private String to;
    private String from;
    private String smtpServer;
    private String username;
    private String password;
    private String subject;
    private String content;
    private boolean ifAuth; //服务器是否要身份认证
    private String filename="";
    private Vector file = new Vector(); //用于保存发送附件的文件名的集合
    private String port="25";//smtp端口
    private final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";


    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    /**
     * 设置SMTP服务器地址
     */
    public void setSmtpServer(String smtpServer){
        this.smtpServer=smtpServer;
    }

    /**
     * 设置发件人的地址
     */
    public void setFrom(String from){
        this.from=from;
    }
    /**
     * 设置显示的名称
     */
    public void setDisplayName(String displayName){
        this.displayName=displayName;
    }

    /**
     * 设置服务器是否需要身份认证
     */
    public void setIfAuth(boolean ifAuth){
        this.ifAuth=ifAuth;
    }

    /**
     * 设置E-mail用户名
     */
    public void setUserName(String username){
        this.username=username;
    }

    /**
     * 设置E-mail密码
     */
    public void setPassword(String password){
        this.password=password;
    }

    /**
     * 设置接收者
     */
    public void setTo(String to){
        this.to=to;
    }

    /**
     * 设置主题
     */
    public void setSubject(String subject){
        this.subject=subject;
    }

    /**
     * 设置主体内容
     */
    public void setContent(String content){
        this.content=content;
    }

    /**
     * 该方法用于收集附件名
     */
    public void addAttachfile(String fname){
        file.addElement(fname);
    }

    public Mail(){

    }

    /**
     * 初始化SMTP服务器地址、发送者E-mail地址、用户名、密码、接收者、主题、内容
     */
    public Mail (String smtpServer,String from,String displayName,String username,String password,String to,String subject,String content){
        this.smtpServer=smtpServer;
        this.from=from;
        this.displayName=displayName;
        this.ifAuth=true;
        this.username=username;
        this.password=password;
        this.to=to;
        this.subject=subject;
        this.content=content;
    }

    /**
     * 初始化SMTP服务器地址、发送者E-mail地址、用户名、密码、接收者、主题、内容  ,端口
     */
    public Mail (String smtpServer,String from,String displayName,String username,String password,String to,String subject,String content,String port){
        this.smtpServer=smtpServer;
        this.from=from;
        this.displayName=displayName;
        this.ifAuth=true;
        this.username=username;
        this.password=password;
        this.to=to;
        this.subject=subject;
        this.content=content;
        this.port = port;
    }

    /**
     * 初始化SMTP服务器地址、发送者E-mail地址、接收者、主题、内容
     */
    public Mail(String smtpServer,String from,String displayName,String to,String subject,String content){
        this.smtpServer=smtpServer;
        this.from=from;
        this.displayName=displayName;
        this.ifAuth=false;
        this.to=to;
        this.subject=subject;
        this.content=content;
    }

    /**
     * 发送邮件
     * @throws Exception
     */
    public HashMap send() throws Exception
    {

        System.setProperty("java.net.preferIPv4Stack", "true"); //DEBUG SMTP: trying to connect to host "127.0.0.1", port 25, isSSL false Could not connect to SMTP host: 127.0.0.1, port: 25;


        HashMap map=new HashMap();
        map.put("state", "success");
        String message="邮件发送成功!";
        Session session=null;
        Properties props = System.getProperties();
        props.put("mail.smtp.host", smtpServer);
        props.put("mail.smtp.port", port);
        // if(ifAuth){ //服务器需要身份认证
        if(1==1){ //服务器需要身份认证

            props.put("mail.smtp.auth","true");
            SmtpAuth smtpAuth=new SmtpAuth(username,password);
            session=Session.getDefaultInstance(props, smtpAuth);
        }else{
            props.put("mail.smtp.auth","false");
            session=Session.getDefaultInstance(props, null);
        }

        //这里暂时增加只处理SSL的开始,以后再把是否SSL做到参数传入,不过目前阿里云服务器只能使用465的SSL模式发邮件
        props.put("mail.smtp.socketFactory.class", SSL_FACTORY);  //使用JSSE的SSL socketfactory来取代默认的socketfactory
        props.put("mail.smtp.socketFactory.fallback", "false");  // 只处理SSL的连接,对于非SSL的连接不做处理
        props.put("mail.smtp.socketFactory.port", port);
        props.put("mail.smtp.starttls.enable", true);
        props.put("mail.smtp.ssl.enable", true);//这句漏掉了导致SSL发送老提示连不上
        props.put("mail.transport.protocol", "smtps"); // 启用smtps方式

        //这里暂时增加只处理SSL的结束
        session.setDebug(false);
        Transport trans = null;
        try {
            Message msg = new MimeMessage(session);
            try{
                Address from_address = new InternetAddress(from, displayName);
                msg.setFrom(from_address);
            }catch(java.io.UnsupportedEncodingException e){
                e.printStackTrace();
            }
            InternetAddress[] address={new InternetAddress(to)};
            msg.setRecipients(Message.RecipientType.TO,address);
            //msg.setSubject(subject);   //这个地方加个日期时分秒,可能会防止被认为是垃圾邮件
            msg.setSubject(subject+" "+ StringUtil.getCurrentDateTime());
            Multipart mp = new MimeMultipart();
            MimeBodyPart mbp = new MimeBodyPart();
            mbp.setContent(content.toString(), "text/html;charset=gb2312");
            mp.addBodyPart(mbp);
            if(!file.isEmpty()){//有附件
                Enumeration efile=file.elements();
                while(efile.hasMoreElements()){
                    mbp=new MimeBodyPart();
                    filename=efile.nextElement().toString(); //选择出每一个附件名
                    FileDataSource fds=new FileDataSource(filename); //得到数据源
                    mbp.setDataHandler(new DataHandler(fds)); //得到附件本身并至入BodyPart
                    mbp.setFileName(MimeUtility.encodeText(filename));//这里的GB2312我认为应该和161行的设置称一致

                    //
                    mp.addBodyPart(mbp);

                }
                file.removeAllElements();
            }
            msg.setContent(mp); //Multipart加入到信件
            msg.setSentDate(new Date());     //设置信件头的发送日期
            //发送信件
            msg.saveChanges();

            trans = session.getTransport("smtp");
            trans.connect(smtpServer, username, password);


            trans.sendMessage(msg, msg.getAllRecipients());

            trans.close();

        }catch(AuthenticationFailedException e){
            map.put("state", "failed");
            message="邮件发送失败!错误原因:\n"+"身份验证错误!";
            throw new Exception("邮箱认证失败!");
            //e.printStackTrace();
        }catch (MessagingException e) {
            message="邮件发送失败!错误原因:\n"+e.getMessage();
            map.put("state", "failed");

            throw new Exception("MessagingException:"+e.toString());
        }
        //System.out.println("\n提示信息:"+message);
        map.put("message", message);
        return map;
    }

    public static void main(String args[]) throws Exception
    {
        String content="<html><body><h2>SpringBoot学习<h2></body></html>";
        String smtpAddr = "smtp.163.com";
        String sendEmail = "xxx@163.com";
        String senderName = "openjweb";
        String senderMailLoginId = "xxx@163.com";
        String pwd = "111111";
        String toMail = "yyy@qq.com";//接收者邮箱
        String mailTitle = "我再次给自己发了个邮件";
        Mail mail = new Mail(smtpAddr,sendEmail,senderName,senderMailLoginId,
                pwd,toMail,mailTitle,content,"465");
        mail.addAttachfile("d:\\pic\\water.png");
        mail.send();
    }


}

        在main方法中演示了带附件的邮件发送。注意在邮件发送测试时,要在公网环境中进行测试。完整示例代码见github:

GitHub - openjweb/cloud at masterOpenJWeb is a java bases low code platform. Contribute to openjweb/cloud development by creating an account on GitHub.icon-default.png?t=O83Ahttps://github.com/openjweb/cloud/tree/master


http://www.kler.cn/a/427694.html

相关文章:

  • Docker的彻底删除与重新安装(ubuntu22.04)
  • QT实战--带行号的支持高亮的编辑器实现(1)
  • Android12-Framework开机自启服务-应用-自动执行-循环检测
  • ORACLE表数据还原
  • 漫画之家:Spring Boot技术实现的漫画资源平台
  • 百度ueditor富文本插件多图片上传顺序混乱问题
  • JavaScript动态网络爬取:深入解析与实践指南
  • 分类算法中的样本不平衡问题及其解决方案
  • 鸿蒙实现数据管理
  • vue elementui layout布局组件实现规则的弹性布局
  • Qt Designer Ui设计
  • 分苹果(Java Python JS C++ C )
  • 使用前,后端写 具有分页效果的数据展示
  • 二刷代码随想录第24天
  • 敖汉宝塔油页岩露天矿山安全自动化监测
  • Java学习教程,从入门到精通,Java 断言(Assert)语法知识点及案例代码(52)
  • AIDD-人工智能药物设计-化学自然语言引导的扩散式类药分子编辑:DiffIUPAC的魔法之旅
  • leetcode 23. 合并 K 个升序链表
  • # issue 9 进程
  • go语言的zero框架下goctl的安装与配置以及使用