后台发送模板邮件两种解决方案

下面介绍两种发送模板邮件的方法,第一种适合springboot和对thymleaf模板语法比较精通的开发者,第二种则比较通用,因为仅使用了apache-commons-mail和vecolity模板引擎,语法简单容易上手,通用性强,所以个人比较喜欢用第二种。

一、 使用springboot-starter-mail和thymeleaf发送模板邮件

1. 首先引入依赖

    <!-- 添加spring-boot-starter-mail包引用 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <!--thymeleaf 模板技术 用于发送邮件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

2. 相关的配置

        spring.mail.host=smtp.163.com
        spring.mail.username=***
        spring.mail.password=**** //需要去邮件服务器后台获取授权码,此为授权码
        spring.mail.default-encoding=UTF-8
        spring.mail.properties.mail.smtp.auth=true
        spring.mail.properties.mail.smtp.starttls.enable=true
        spring.mail.properties.mail.smtp.starttls.required=true
        spring.thymeleaf.cache=false
                 ##  表示邮件模板存放于该目录下
        spring.thymeleaf.prefix=classpath:/mailtemplate/ 
        spring.thymeleaf.suffix=.html
        spring.thymeleaf.content-type=text/html

3. 根据模板生成相应html

    //模板引擎对象
    @Autowired
    private TemplateEngine templateEngine;

     //获取生成的模板
         Map<String, String> dataMap = new HashMap<>();
        dataMap.put("title", "用户名激活");
        dataMap.put("url", "233");
        Context context = new Context();
        context.setVariables(dataMap);
        String emailText = templateEngine.process("emailTemplates", context);

4. 发送邮件

 @Autowired
    private JavaMailSender javaMailSender;

     @Override
    public void sendHtml(String to, String subject) {
        try {
        
            //获取生成的模板
            Map<String, String> dataMap = new HashMap<>();
            dataMap.put("title", "用户名激活");
            dataMap.put("url", "233");
            Context context = new Context();
            context.setVariables(dataMap);
            String emailText = templateEngine.process(templatesName, context);
            //消息处理助手对象
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //设置发件人
            helper.setFrom(sender);
            //设置收件人
            helper.setTo(to);
            //设置邮件标题
            helper.setSubject("主题:用户名激活");
            //设置邮件内容 ,true 表示发送html 格式
            helper.setText(emailText, true);
            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

5. 附件:html模板(需掌握thymleaf模板语法: https://www.cnblogs.com/jiangbei/p/8462294.html)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>userInfo</title>
</head>
<body>
title: <span th:text="${title}"></span>
</body>
</html>

二、使用apache-commons-mail包和 vecolity 模板引擎来发送模板邮件

  1. 依赖
 <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-email</artifactId>
            <version>1.5</version>
        </dependency>

  <!--模板引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
  1. 根据模板生成 html文件或者 html 的字符串
## 模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试velocity模板</title>
</head>
<body>
    #if(${var1})
        <p>获取变量: ${var1}</p>
    #end
<br/>
<p>测试循环:</p>
<ul>
    #foreach($pkg in ${var2})
            <li style="color:red">$pkg</li>
    #end
</ul>
</body>
</html>

## 渲染模板
public class RenderUtils {

    public static final String encode = Charset.forName("UTF-8").name();

    public static void main(String[] args) {
        System.out.println(getVmRenderString("/vmtpl.vm",
                new HashMap<String, Object>() {{
                    put("var1", "测试");
                    put("var2", Arrays.asList("4", "5", "6"));
                }}
        ));
    }

    /**
     * 根据velocity引擎生成文件
     *
     * @param templatePath resource文件夹下的模板地址,如:/vmtempalte/vmtpl.vm
     * @param outputFile   输出文件地址
     * @param objectMap    变量值:
     *                     <p>
     *                     模板插值判断语法:
     *                     #if(${restControllerStyle})
     *                     #else
     *                     #end
     *                     <p>
     *                     模板插值循环语法:
     *                     #foreach($pkg in ${table.importPackages})
     *                     import ${pkg};
     *                     #end
     */
    public static void getFileByVmEngine(String templatePath, String outputFile, Map<String, Object> objectMap) {
        try {
            VelocityEngine velocityEngine = initVelocityEngine();
            Template template = velocityEngine.getTemplate(templatePath, encode);
            FileOutputStream fos = new FileOutputStream(outputFile);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, encode));
            template.merge(new VelocityContext(objectMap), writer);
            writer.close();
        } catch (IOException e) {
            System.out.println("根据模版引擎生成目标失败");
            e.printStackTrace();
        }
    }

    /**
     * 根据velocity引擎生成文件
     *
     * @param templatePath resource文件夹下的模板地址,如:/vmtempalte/vmtpl.vm
     * @param objectMap    变量值:
     *                     <p>
     *                     模板插值判断语法:
     *                     #if(${restControllerStyle})
     *                     #else
     *                     #end
     *                     <p>
     *                     模板插值循环语法:
     *                     #foreach($pkg in ${table.importPackages})
     *                     import ${pkg};
     *                     #end
     */
    public static String getVmRenderString(String templatePath, Map<String, Object> objectMap) {
        String render = "";
        try {
            VelocityEngine velocityEngine = initVelocityEngine();
            Template template = velocityEngine.getTemplate(templatePath, encode);
            StringWriter writer = new StringWriter();
            template.merge(new VelocityContext(objectMap), writer);
            render = writer.getBuffer().toString();
            writer.close();
        } catch (IOException e) {
            System.out.println("根据模版引擎生成目标失败");
            e.printStackTrace();
        } finally {
            return render;
        }
    }

    private static VelocityEngine initVelocityEngine() {
        Properties p = new Properties();
        p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        p.setProperty("file.resource.loader.path", "");
        p.setProperty("UTF-8", encode);
        p.setProperty("input.encoding", encode);
        p.setProperty("file.resource.loader.unicode", "true");
        return new VelocityEngine(p);
    }
}
  1. 发送邮件
 /**
     * 发送html邮件
     *
     * @param host
     * @param userName
     * @param sercet
     * @param from
     * @param to
     * @param subject
     * @param html
     */
    public static void sendHtml(String host, String userName, String sercet, String from, String to, String subject, String html) {
        try {
            //内嵌图片方式1
            //        URL url = new URL("http://www.apache.org/images/asf_logo_wide.gif");
//        String cid = email.embed(url, "Apache logo");
            //内嵌图片方式2
            //        String htmlEmailTemplate = ".... <img src=\"http://www.apache.org/images/feather.gif\"> ....";
//        URL url = new URL("http://www.apache.org");
//        ImageHtmlEmail email = new ImageHtmlEmail();
//        email.setDataSourceResolver(new DataSourceUrlResolver(url));
            HtmlEmail email = new HtmlEmail();
            email.setHostName(host);
            email.setAuthenticator(new DefaultAuthenticator(userName, sercet));
            email.setFrom(from);
            if (to.indexOf(",") == -1) {
                email.addTo(to);
            } else {
                List<String> list = Arrays.asList(to.split(","));
                for (String s : list) {
                    email.addTo(s);
                }
            }
            email.setSubject(subject);
//            email.setHtmlMsg(html);
            email.setCharset("gbk");
            email.setMsg(html);
            email.send();
        } catch (EmailException e) {
            e.printStackTrace();
        }
    }


    /**
     * 普通文本1
     *
     * @throws EmailException
     */
    public static void sendText(String host, String userName, String sercet, String from, String to, String subject, String text) {
        try {
            Email email = new SimpleEmail();
            email.setHostName(host);
//        email.setSmtpPort(465);
            // 用户名和密码为邮箱的账号和密码(不需要进行base64编码)
            email.setAuthenticator(new DefaultAuthenticator(userName, sercet));
//        email.setSSLOnConnect(true);
            email.setFrom(from);
            if (to.indexOf(",") == -1) {
                email.addTo(to);
            } else {
                List<String> list = Arrays.asList(to.split(","));
                for (String s : list) {
                    email.addTo(s);
                }
            }
            email.setSubject(subject);
            email.setMsg(text);
            email.send();
        } catch (EmailException e) {
            e.printStackTrace();
        }
    }
  1. 调用
 public static void main(String[] args) throws Exception {
        String html = "";
        System.out.println(html = RenderUtils.getVmRenderString("\\vmtempalte\\vmtpl.vm",
                new HashMap<String, Object>() {{
                    put("var1", "测试");
                    put("var2", Arrays.asList("555", "5", "6"));
                }}
        ));
        MailHelper.sendHtml(BianMailDto.builder()
                .host("smtp.163.com")
                .userName("邮箱账号")
                .sercet("邮箱授权码")
                .from("发送者")
                //逗号分隔发送多位
                .to("接受者")
                .subject("测试标题")
                .html(html).build());
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 从莲花岛回到花间晚照宾馆已是下午2时多了,有同学说要在宾馆休息一下。这时,张敏对我说:“我在蚌埠太平街长大的,我想...
    蒋坤元阅读 1,592评论 4 8
  • 我的祖国,叫中国,每当听到这个名字,心里总有一种难以言表的感动和激动。 我爱我的祖国!它不仅赋予了我生...
    千柚阅读 409评论 0 0
  • 在电脑上学习CAD应该使用哪一款CAD看图软件呢?对于新手而又是从事CAD之类相关工作的人来说,选择一款好用的CA...
    周周周大璇阅读 129评论 0 0
  • 许久没有摸相机了,出门溜达时拍了些照片,图片也是记录的一种方式,给了我更多的触角审视我们生活的世间。图片均为原创。...
    隐梦尤阅读 765评论 0 0