Java(SpringCloud) 使用Thymeleaf渲染模板,通过Mailgun发送邮件

12 篇文章 0 订阅
4 篇文章 0 订阅

好久没发博客了,忙东忙西的,坚持!

本文介绍Java使用Mailgun搭建发送邮件的服务。


我把这个邮件服务放在了我的springCloudApplication(微服务Demo)项目的utilservice服务模块中。
源码地址:springCloudApplication

  • jdk1.8
  • SpringBoot版本:2.0.4.RELEASE
  • SpringCloud版本:Finchley.RELEASE
  • Intellij IDEA :2018-2

本文涉及到基础的SpringCloud 知识,对应到本项目中的服务名来说就是:服务注册中心(eurekaserver),配置中心(configserver),路由(routeservice),负载均衡服务调用(uaaservice)。


一、Mailgun

Mailgun是国外的一个邮件服务器。主页:https://app.mailgun.com/

其实代码没多少,就是配置Mailgun需要花费些时间。

先用邮箱注册好。
在这里插入图片描述

Settings,显示的就是你的账户信息。
Security,这里的 Private API Key 就是等会要用到的身份认证key。
在这里插入图片描述
Authorized Recipients
在这里插入图片描述
Upgrade,升级账户,貌似是$1。绑定你的信用卡。
在这里插入图片描述
接下来跳转到:https://app.mailgun.com/app/domains
domains,域名。上面个是我自己的域名(这里本该解析个二级域名的,我直接用顶级域名搞了一次),下面个是当你注册账户时Mailgun为你自动生成的一个二级域名。
在这里插入图片描述
刚开始进这个页面是只有下面个域名,自己的域名要通过Add New Aomain添加。
在这里插入图片描述
添加完之后你的域名会显示:Unverified,点击自己的域名验证,往下拉,看Domain Verification & DNS部分
在这里插入图片描述
要去自己的域名服务商控制台配置,我这里全都配置好了所以全绿。我的域名阿里云买的,解析记录如下:
在这里插入图片描述
看着这个GIF跟着配置就好了:https://help.mailgun.com/hc/en-us/articles/202052074-How-do-I-verify-my-domain-
我还添加了个SMTP Credentials:
在这里插入图片描述
在这里插入图片描述
好,现在Mailgun配置算是完成了。接下来上代码。还有啥问题就翻它的文档吧。


二、代码

我这里写了两种方式的邮件内容,一种纯文本内容的,一种thymeleaf模板引擎渲染的html内容的。就放在一起写了。只上核心代码和配置。详细了解看源码,文章开头已给出地址。
项目结构:
在这里插入图片描述

  • eurekaserver,服务注册中心
  • confiserver,配置中心,几乎所有功能模块的配置都放在这里的
  • routeserver,路由网关
  • utilservice,邮件服务所在模块
  • uaaservice,在这里调用邮件服务
调用服务时传入收件人邮箱List,邮件的主题,邮件的thymeleaf模板,模板的参数(Map<String,Object>)。然后在邮件服务中渲染模板,然后通过mailgun发送邮件。

mailgun配置属性:

mailgun:
  domain: mistra.wang
  apiKey: key-e9861fdc2c1a6f189528c9cf18c5dc1a
  from: 丶小王瑞
  fromAddress: rui@mistra.wang
  mailgunResource: https://api.mailgun.net/v3/mistra.wang/messages

注意:如果写代码的时候把这个配置,就是你的mailgun的敏感信息,如key等。push到了Github的公共仓库的话你的邮件服务用不了,你的账户会被禁用。并且你会收到邮件提示,如何解决。记得测试完了代码再push。还挺严谨安全的,我测试完,刚push,马上我的账户就用不了了。
在这里插入图片描述
配置属性安全映射实体类

@Data
@Configuration
@ConfigurationProperties(prefix = "mailgun")
public class MailgunConfigProperties {
    private String domain;
    private String apiKey;
    private String from;
    private String fromAddress;
    private String mailgunResource;
}

MailgunConfig配置

@Configuration
public class MailgunConfig {
    /**
     * mailgun配置参数
     */
    @Autowired
    private MailgunConfigProperties mailgunConfigProperties;

    @Bean
    public net.sargue.mailgun.Configuration mailgunConfiguration(){
        net.sargue.mailgun.Configuration configuration = new net.sargue.mailgun.Configuration()
                .from(mailgunConfigProperties.getFrom(), mailgunConfigProperties.getFromAddress())
                .apiKey(mailgunConfigProperties.getApiKey())
                .domain(mailgunConfigProperties.getDomain());
        return configuration;
    }
}

thymeleaf模板引擎配置

@Configuration
public class SpringTemplateEngineConfig {

    @Bean(name = "stringTemplateEngine")
    public SpringTemplateEngine springTemplateEngine() {
        //字符串模板引擎对象
        SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
        //内置方言
        IDialect springStandardDialect = new SpringStandardDialect();
        springTemplateEngine.setDialect(springStandardDialect);
        //字符串解析器
        StringTemplateResolver stringTemplateResolver = new StringTemplateResolver();
        //使用缓存
        stringTemplateResolver.setCacheable(true);
        stringTemplateResolver.setTemplateMode(TemplateMode.HTML);
        springTemplateEngine.setTemplateResolver(stringTemplateResolver);
        return springTemplateEngine;
    }
}

线程池Bean

@Component
public class ThreadPoolConfig extends ThreadPoolTaskExecutor {

}

邮件实体

@Data
public class MailDTO {
    /**
     * 发送对象
     */
    @NotEmpty
    private List<String> sendToAddress;
    /**
     * 主题
     */
    @NotNull
    private String subject;
    /**
     * 模板
     */
    @NotNull
    private String template;
    /**
     * 模板参数
     */
    @NotNull
    private Map<String,Object> paramsMap;
}

service

package com.mistra.utilservice.service.impl;

import com.mistra.base.result.Result;
import com.mistra.utilservice.config.MailgunConfigProperties;
import com.mistra.utilservice.dto.MailDTO;
import com.mistra.utilservice.service.MailService;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import net.sargue.mailgun.*;
import net.sargue.mailgun.content.Body;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.ws.rs.core.MediaType;
import java.util.regex.Pattern;

/**
 * @Author: WangRui
 * @Date: 2018/10/14
 * Time: 下午10:35
 * Description:
 */
@Service
public class MailServiceImpl implements MailService {

    private Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);

    /**
     * 邮箱验证正则
     */
    public static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";

    /**
     * 字符串模板解析引擎
     */
    @Qualifier("stringTemplateEngine")
    @Autowired
    private SpringTemplateEngine springTemplateEngine;

    @Autowired
    private Configuration mailgunConfiguration;

    @Autowired
    private MailgunConfigProperties mailgunConfigProperties;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public Result sendMail(MailDTO mailDTO) {
        return sendTwo(mailDTO);
    }

    public Result sendOne(MailDTO mailDTO) {
        Result result = new Result();
        if (mailDTO.getSendToAddress().size() == 0 || mailDTO.getParamsMap().size() == 0 || StringUtils.isEmpty(mailDTO.getSubject()) || StringUtils.isEmpty(mailDTO.getTemplate())) {
            result.setSuccess(false);
            result.setMessage("MailDTO参数不正确!");
            return result;
        }
        for (String to : mailDTO.getSendToAddress()) {
            if (!Pattern.matches(REGEX_EMAIL, to)) {
                result.setSuccess(false);
                result.setMessage("邮箱格式错误!");
                return result;
            }
        }
        //编译thymeleaf模板 渲染数据
        Context context = new Context();
        context.setVariables(mailDTO.getParamsMap());
        String mailContent = springTemplateEngine.process(mailDTO.getTemplate(), context);
        Body mailBody = new Body(mailContent, "");

        MailBuilder mailBuilder = Mail.using(mailgunConfiguration);
        mailBuilder.subject(mailDTO.getSubject());
        mailBuilder.content(mailBody);
        for (String sendTo : mailDTO.getSendToAddress()) {
            mailBuilder.to(sendTo);
        }
        result.setSuccess(false);
        result.setMessage("邮件发送成功!");
        threadPoolTaskExecutor.submit(() -> {
            Response response = mailBuilder.build().send();
            logger.info("Send mail complete. Code: {}, Response Type: {}. Message: {}", response.responseCode(), response.responseType(), response.responseMessage());
            if (response.responseCode() != 200) {
                result.setSuccess(false);
                result.setMessage("邮件发送失败!" + response.responseMessage());
            }
        });
        return result;
    }

    /**
     * 第二种 发送纯文本邮件
     *
     * @param mailDTO
     * @return
     */
    public Result sendTwo(MailDTO mailDTO) {
        Result result = new Result();
        Client client = Client.create();
        client.addFilter(new HTTPBasicAuthFilter("api", mailgunConfigProperties.getApiKey()));
        WebResource webResource = client.resource(mailgunConfigProperties.getMailgunResource());
        MultivaluedMapImpl formData = new MultivaluedMapImpl();
        formData.add("from", mailgunConfigProperties.getFrom() + "" + mailgunConfigProperties.getFromAddress());
        mailDTO.getSendToAddress().stream().forEach(temp -> formData.add("to", temp));
        formData.add("subject", mailDTO.getSubject());
        formData.add("text", "纯文本邮件测试!");
        webResource.type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class, formData);
        return result;
    }
}


三、查看Mailgun日志

你可以看到每一次发送邮件的日志,报错原因。
在这里插入图片描述
这个错误就是我的账户被禁用了,暴露了账户凭证,就是我把我的账户信息push到了Github公共仓库引起的。覆盖提交Commit是不管用的了,它提示你删库0-0,麻蛋。

"reject": {
        "reason": "exposed account credentials",
        "description": ""
    },

在这里插入图片描述

全文完。另外我是马自达粉。嘿嘿。


在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要搭建Spring Boot使用Thymeleaf视图模板进行Web开发的环境,可以按照以下步骤进行: 1. 创建Spring Boot项目 可以使用Spring Initializr或者IDE(如IntelliJ IDEA)创建一个Spring Boot项目,选择Web和Thymeleaf作为依赖项。 2. 添加Thymeleaf配置 在应用程序的配置文件中(如application.properties或application.yml),添加以下配置: ``` spring.thymeleaf.cache=false spring.thymeleaf.enabled=true spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html ``` 这里的配置指定了Thymeleaf模板文件所在的路径和后缀名。 3. 创建Thymeleaf模板 在src/main/resources/templates目录下创建一个HTML文件,并添加Thymeleaf的标签和表达式。例如: ``` <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Thymeleaf Example</title> </head> <body> <h1 th:text="${message}">Hello World!</h1> </body> </html> ``` 这个示例使用Thymeleaf的th:text标签将一个变量message的值输出到页面上。 4. 创建控制器类 创建一个控制器类,处理HTTP请求并返回Thymeleaf模板。例如: ``` @Controller public class HomeController { @GetMapping("/") public String home(Model model) { model.addAttribute("message", "Hello from Thymeleaf!"); return "home"; } } ``` 这个示例中,控制器类处理根路径的GET请求,并将一个名为message的变量添加到模型中。最后,返回一个名为“home”的字符串,它与Thymeleaf模板的名称对应。 5. 运行应用程序 运行应用程序并在浏览器中打开http://localhost:8080/,您将看到Thymeleaf渲染的页面,其中包含控制器方法中添加的消息。 到这里,您就成功地搭建了Spring Boot使用Thymeleaf视图模板进行Web开发的环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值