zoukankan      html  css  js  c++  java
  • 发送邮件【文本-html】【图片】【邮件】【附件】

    
    
    依赖
    
     <!-- https://mvnrepository.com/artifact/javax.mail/mail -->
            <dependency>
                <groupId>javax.mail</groupId>
                <artifactId>mail</artifactId>
                <version>1.4.7</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
            <dependency>
                <groupId>javax.activation</groupId>
                <artifactId>activation</artifactId>
                <version>1.1.1</version>
            </dependency>
    
    
    package com.rjj.demo.tools.mail;
    
    import com.jfinal.log.Log;
    import com.sun.mail.util.MailSSLSocketFactory;
    
    import javax.activation.DataHandler;
    import javax.activation.DataSource;
    import javax.activation.FileDataSource;
    import javax.mail.*;
    import javax.mail.internet.*;
    import java.io.UnsupportedEncodingException;
    import java.security.GeneralSecurityException;
    import java.security.Security;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Properties;
    
    /**
     ** 邮件
     *  * 1.普通文本 sendText  html消息  sendHtml
     *  * 2.图片
     *  * 3.附件 sendFile
     *  * 4.文本+图片 sendTextPhoto
     *  * 5.图片文本附件 sendTextPhotoFile
     *  * 6.抄送,密送
     *  * 7.群发【普通发送的时候把发送地址拼接字符串a,b.c】
     */
    public class MailUtilMe {
    
        private Log logger = Log.getLog(MailUtil.class);
    
        //发件箱
        private String fromEmail = "215060580@qq.com";
        //发件箱别名
        private String personel = "淡淡人生过";
        //发件箱密码
        private String password = "rylihxxxxxxzcajb";
        //端口
        private String port = "465";
        //主机地址
        private String host = "smtp.qq.com";
        //收件人邮箱
        private String toEmail = "253481340@qq.com";
        //主题
        private String subject ="淡淡人生过的第一份邮件";
    
    
        //获取基本配置,这种可能会报错
    
        /**
         * 会报错javax.net.ssl.SSLHandshakeException:
         * sun.security.validator.ValidatorException:
         * PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
         * unable to find valid certification path to requested target
         *
         * 错误很简单,就是证书路径无效,网上有人说使用代码下载证书到本地jre证书库中,
         * 或者直接导入此证书到jre证书;确实可以;但是我们可以在代码中信任此站点证书
         * @return
         */
        public Properties getProperties(){
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
            Properties props = System.getProperties();
            props.setProperty("mail.host", host);//主机
            props.put("mail.transport.protocol", "smtp");//链接协议
            props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
            props.setProperty("mail.smtp.socketFactory.fallback", "false");
            props.setProperty("mail.smtp.port", port);
            props.setProperty("mail.smtp.socketFactory.port", port);
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.starttls.enable","true");//开启ssl加密
            props.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
            return props;
        }
    
        /**
         * 基本不会出现问题
         * @return
         */
        public Properties getProp(){
    
            Properties props = System.getProperties();
            props.setProperty("mail.host", host);//主机地址
            props.put("mail.transport.protocol", "smtp");//链接协议
            props.setProperty("mail.smtp.port", port);//端口
            props.put("mail.smtp.auth", "true"); // 允许smtp校验
            MailSSLSocketFactory sf = null;
            try {
                sf = new MailSSLSocketFactory();
                sf.setTrustAllHosts(true);
            } catch (GeneralSecurityException e) {
                logger.info("error", e);
            }
    
            props.put("mail.smtp.ssl.enable", "true");//开启ssl加密
            props.put("mail.smtp.ssl.socketFactory", sf);
            props.put("mail.smtp.socketFactory.fallback", "false");
            props.put("mail.smtp.socketFactory.port",  port);
            props.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
            return props;
        }
    
        /**
         * 获取session
         */
        public Session getSession(){
            Properties prop = getProp();
            Session session = Session.getDefaultInstance(prop, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(fromEmail,password);
                }
            });
    
            return session;
        }
    
    
        public MimeMessage getMineMessage() {
            Session session = getSession();
    
            // 创建默认的 MimeMessage 对象
            MimeMessage message = new MimeMessage(session);
    
            try {
    
                // Set From: 头部头字段,设置了默认名称,就会显示发送人为 "淡淡人生过"
                message.setFrom(new InternetAddress(fromEmail,personel));
    
                /**
                 * Set To: 头部头字段
                 *
                 * Message.RecipientType.TO  普通发送
                 * Message.RecipientType.CC  抄送
                 * Message.RecipientType.BCC 密送
                 */
                //给一个人发送邮件
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
                //给多个人发送邮件
                //message.addRecipients(Message.RecipientType.TO,new Address[]{new InternetAddress(toEmail),new InternetAddress(toEmail)});
                //message.addRecipients(Message.RecipientType.CC,new Address[]{new InternetAddress(toEmail)});
                //message.addRecipients(Message.RecipientType.BCC,new Address[]{new InternetAddress(toEmail)});
    
                // Set Subject: 头部头字段
                message.setSubject(subject,"UTF-8");
    
                //设置邮件的发送时间
                message.setSentDate(new Date());
    
            } catch (MessagingException e) {
                logger.info("1出现异常:" + e.getMessage());
            } catch (UnsupportedEncodingException e) {
                logger.info("2出现异常:" + e.getMessage());
            }
    
            return message;
        }
    
        /**
         * 发送邮件
         *
         * 普通文本消息
         */
        public void sendText(String content) {
            MimeMessage message = getMineMessage();
            // 设置消息体
            try {
                message.setText(content);
                Transport.send(message);
            } catch (MessagingException e) {
                logger.info("设置文本内容出现异常:" + e.getMessage());
            }
        }
    
        /**
         * 发送邮件
         *
         * html消息
         */
        public void sendHtml(String content){
            MimeMessage message = getMineMessage();
            try {
                message.setContent(content,"text/html;charset=UTF-8");
                Transport.send(message);
            } catch (MessagingException e) {
                logger.info("设置html内容出现异常:" + e.getMessage());
            }
        }
    
        /**
         * 发送带附件的邮件
         */
        public void sendFile(String content, String pathFileName){
            MimeMessage message = getMineMessage();
    
            // 创建多重消息
            Multipart multipart = new MimeMultipart();
    
            try {
    
                // 创建消息部分
                BodyPart messageBodyPart = new MimeBodyPart();
                // 消息,这里的消息不发送也是可以的
               // messageBodyPart.setText(content);
                messageBodyPart.setContent(content, "text/html; charset=utf-8");
    
                // 设置文本消息部分
                multipart.addBodyPart(messageBodyPart);
    
                // 附件部分
                messageBodyPart = new MimeBodyPart();
                //获取文件
                DataSource source = new FileDataSource(pathFileName);
                messageBodyPart.setDataHandler(new DataHandler(source));
                //设置文件名称
                messageBodyPart.setFileName(MimeUtility.encodeText(source.getName()));
                //添加到多重消息容器中
                multipart.addBodyPart(messageBodyPart);
    
                // 发送完整消息
                message.setContent(multipart);
    
                //   发送消息
                Transport.send(message);
            } catch (MessagingException e) {
                logger.info("发送附件邮件出现异常:" + e.getMessage());
            } catch (UnsupportedEncodingException e) {
                logger.info("文件名称编码异常:" + e.getMessage());
            }
        }
    
        /**
         * 多文件下载
         * @param content 信息
         * @param pathFileName 多个附件的路径
         */
        public void sendFileList(String content, List<String> pathFileName){
            MimeMessage message = getMineMessage();
    
            try {
                // 创建多重消息
                Multipart multipart = new MimeMultipart();
    
                //消息
                BodyPart messageBodyPart = new MimeBodyPart();
                messageBodyPart.setContent(content,"text/html; charset=utf-8");
                multipart.addBodyPart(messageBodyPart);
    
                for (String filePath : pathFileName) {
                    // 附件部分
                    // 创建消息部分
                     messageBodyPart = new MimeBodyPart();
                    //获取文件
                    DataSource source = new FileDataSource(filePath);
                    messageBodyPart.setDataHandler(new DataHandler(source));
                    //设置文件名称
                    messageBodyPart.setFileName(MimeUtility.encodeText(source.getName()));
    
                    //添加到多重消息容器中
                    multipart.addBodyPart(messageBodyPart);
                }
                // 发送完整消息
                message.setContent(multipart);
    
                //   发送消息
                Transport.send(message);
            } catch (MessagingException e) {
                logger.info("发送附件邮件出现异常:" + e.getMessage());
            } catch (UnsupportedEncodingException e) {
                logger.info("文件名称编码异常:" + e.getMessage());
            }
        }
    
        /**
         * 发送图片和附件邮件
         */
        public void sendTextPhotoFile(){
            String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg";
            MimeMessage message = getMineMessage();
    
            try {
                // 1.创建图片"节点"
                MimeBodyPart image = new MimeBodyPart();
                // 读取本地文件
                DataHandler dh = new DataHandler(new FileDataSource(pathName));
                // 将图片数据添加到"节点"
                image.setDataHandler(dh);
                // 为"节点"设置一个唯一编号(在文本"节点"将引用该ID)
                image.setContentID("mailTestPic");
    
                // 2. 创建文本"节点"
                MimeBodyPart text = new MimeBodyPart();
                // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
                /**
                 *
                 这里在img标签中src属性中添加了cid:mailTestPic  其实就是把图片和我发送的图片关联起来了,点击图片就会跳到我的路径所在的地址
                 这里使用a标签包裹了,我的图片,发送的内容其实时html的,所以有些标签不显示,其实一html的标签
                 */
                text.setContent(
                        "这是一张图片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'>" + //我想要点击图片跳到的地址
                                "<img src='cid:mailTestPic'/>" + //图片,可以写网络图片的地址
                                "</a>"
                        , "text/html;charset=UTF-8");//html,使用utf-8,识别
    
                // 3. (文本+图片)设置 文本 和 图片"节点"的关系(将 文本 和 图片"节点"合成一个混合"节点")
                MimeMultipart mm_text_image = new MimeMultipart();
                mm_text_image.addBodyPart(text);
                mm_text_image.addBodyPart(image);
                mm_text_image.setSubType("related");    // 关联关系
    
                // 4. 将 文本+图片 的混合"节点"封装成一个普通"节点"
                // 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
                // 上面的 mailTestPic 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
                MimeBodyPart text_image = new MimeBodyPart();
                text_image.setContent(mm_text_image);
    
                // 5. 创建附件"节点"
                MimeBodyPart attachment = new MimeBodyPart();
                // 读取本地文件
                DataHandler dh2 = new DataHandler(new FileDataSource(pathName));
                // 将附件数据添加到"节点"
                attachment.setDataHandler(dh2);
                // 设置附件的文件名(需要编码)
                attachment.setFileName(MimeUtility.encodeText(dh2.getName()));
    
                // 6. 设置(文本+图片)和 附件 的关系(合成一个大的混合"节点" / Multipart )
                MimeMultipart mm = new MimeMultipart();
                mm.addBodyPart(text_image);
                mm.addBodyPart(attachment);     // 如果有多个附件,可以创建多个多次添加
                mm.setSubType("mixed");         // 混合关系
    
                // 7. 设置整个邮件的关系(将最终的混合"节点"作为邮件的内容添加到邮件对象)
                message.setContent(mm);
                Transport.send(message);
    
            } catch (MessagingException e) {
                logger.info("图片文本文件消息异常:" + e.getMessage());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
    
        }
        public void sendTextPhoto(){
            String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg";
            MimeMessage message = getMineMessage();
    
            try {
                // 1.创建图片"节点"
                MimeBodyPart image = new MimeBodyPart();
                // 读取本地文件
                DataHandler dh = new DataHandler(new FileDataSource(pathName));
                // 将图片数据添加到"节点"
                image.setDataHandler(dh);
                // 为"节点"设置一个唯一编号(在文本"节点"将引用该ID)
                image.setContentID("mailTestPic");
    
                // 2. 创建文本"节点"
                MimeBodyPart text = new MimeBodyPart();
                // 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
                /**
                 *
                 这里在img标签中src属性中添加了cid:mailTestPic  其实就是把图片和我发送的图片关联起来了,点击图片就会跳到我的路径所在的地址
                 这里使用a标签包裹了,我的图片,发送的内容其实时html的,所以有些标签不显示,其实一html的标签
                 */
                text.setContent(
                        "这是一张图片<br/><a href='http://www.cnblogs.com/ysocean/p/7666061.html'>" + //我想要点击图片跳到的地址
                                "<img src='cid:mailTestPic'/>" + //图片,可以写网络图片的地址
                                "</a>"
                        , "text/html;charset=UTF-8");//html,使用utf-8,识别
    
                // 3. (文本+图片)设置 文本 和 图片"节点"的关系(将 文本 和 图片"节点"合成一个混合"节点")
                MimeMultipart mm_text_image = new MimeMultipart();
                mm_text_image.addBodyPart(text);
                mm_text_image.addBodyPart(image);
                /**
                 * 邮件体包含邮件的内容,它的类型由邮件头的“Content-Type”域指出。常见的简单类型有text/plain(纯文本)和text/html(超文本)。有时也会出现的multipart类型,是MIME邮件的精髓。邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/related和multipart/alternative。
                 *
                 * multipart/mixed:附件。
                 *
                 * multipart/related:内嵌资源。
                 *
                 * multipart/alternative:纯文本与超文本共存。
                 */
                mm_text_image.setSubType("mixed");    // 关联关系,这里图片相当于附件了,只是在正文内容中一img标签显示出来了
    
                // 7. 设置整个邮件的关系(将最终的混合"节点"作为邮件的内容添加到邮件对象)
                message.setContent(mm_text_image);
                Transport.send(message);
    
            } catch (MessagingException e) {
                logger.info("发送文本图片消息出现异常:" + e.getMessage());
            }
    
        }
    
        public static void main(String[] args) {
            String pathName = "/Users/renjianjun/study/ideaWorkSpace/jfinal_demo/src/main/webapp/static/img/lyf.jpg";
    
            MailUtilMe m = new MailUtilMe();
            //m.sendTextPhotoFile();
            //m.sendText("a");
            //m.sendHtml("<b>你好</b>");
            // m.sendFile("刘亦菲哦",pathName);
           // m.sendTextPhoto();
    
            List<String> list = new ArrayList<>(2);
            list.add("/Users/renjianjun/study/ideaWorkSpace/demo/src/main/resources/static/img/lyf.jpg");
            list.add("/Users/renjianjun/study/ideaWorkSpace/demo/src/main/resources/static/img/lyf.jpg");
            m.sendFileList("刘亦菲",list);
        }
    }
  • 相关阅读:
    C# 两个List泛型用lamada表达式去重复数据 或者 得到重复数据
    基于模版文件复制替换的abpcore代码生成器(一)
    基于数据库的vs2019的T4模版代码生成器(二)基于mysql数据库
    基于数据库的vs2019的T4模版代码生成器(一)基于sqlserver数据库
    前后端分离开发vue+Elementyui+abpcorewebapi商城管理系统(十六)项目总结
    前后端分离开发vue+Elementyui+abpcorewebapi商城管理系统(十五)项目上线
    前后端分离开发vue+Elementyui+abpcorewebapi商城管理系统(十四)项目优化
    前后端分离开发vue+Elementyui+abpcorewebapi商城管理系统(十三)报表开发
    前后端分离开发vue+Elementyui+abpcorewebapi商城管理系统(十二)订单列表页面
    前后端分离开发vue+Elementyui+abpcorewebapi商城管理系统(十一)之二 添加商品页面
  • 原文地址:https://www.cnblogs.com/renjianjun/p/10333205.html
Copyright © 2011-2022 走看看