使用 Spring Boot 和 Spring Cloud PlatoBlockchain 数据智能的简单电子邮件服务 (AWS SES) 指南。 垂直搜索。 人工智能。

使用 Spring Boot 和 Spring Cloud 的简单电子邮件服务 (AWS SES) 指南

介绍

AWS SES(简单电子邮件服务) 是一种易于设置的电子邮件发送和接收服务。 管理内部部署的电子邮件系统通常是困难、挑剔和乏味的,因此外包流程是一种流行的选择。

我们可以使用 Amazon SES 向我们的客户发送交易电子邮件、营销电子邮件或任何其他类型的通知电子邮件。 对于使用电子邮件与客户联系的各种规模的企业来说,这是一种经济实惠的解决方案,因为它建立在可靠且可扩展的基础架构之上 亚马逊网络服务(AWS).

为了发送批量电子邮件,任何应用程序都可以与 Amazon SES 交互。 我们只为实际发送的电子邮件付费,无论是交易电子邮件还是营销电子邮件。 此外,Amazon SES 支持一系列配置,包括专用、共享或拥有的 IP 地址。 企业可以使用可传递性仪表板和发件人信息报告来计算每封电子邮件。

在本指南中,我们将在一个区域中配置一个 AWS SES 实例,然后与 适用于 AWS 的春季云 这是一个子项目 春云. 我们将尝试不同的场景来从我们的应用程序发送电子邮件。

请注意: 您可以找到指南中使用的所有源代码 Github上.

使用 AWS SES 发送电子邮件的生命周期

让我们看看应用程序发送的电子邮件的生命周期如何到达目标邮箱:

  • 一个应用程序,在我们的例子中,Spring Cloud 代码请求 AWS SES 向一个或多个收件人发送电子邮件。

  • SES 最初会验证请求,如果获得批准,则会生成一封包含请求规范的电子邮件消息。 此电子邮件消息有标题、正文和信封,并符合 RFC 5322的 Internet 消息格式定义。

  • SES 然后通过 Internet 将消息传输到收件人的接收者。 一旦消息被移交给 SES,它通常会立即传输,初始交付尝试通常在几毫秒内发生。

  • 这个时候有几个结果。 例如:

    • 成功交付:互联网服务提供商 (ISP) 接受电子邮件并将其发送给预定的收件人。
    • 硬弹:因为收件人的地址无效,ISP 拒绝了该电子邮件。 ISP 将硬退回通知发送回 Amazon SES,后者通过电子邮件或将其发布到设置为接收此通知的 Amazon Simple Notification Service (Amazon SNS) 主题来通知发件人。
    • 软弹跳: 由于收件人的收件箱已满、域不存在等情况,或 ISP 太忙而无法处理请求等任何路过情况,ISP 可能无法将电子邮件发送给收件人。 然后,ISP 会重试电子邮件达到一定次数,并向 SES 发送一条软弹回消息。 如果 SES 无法在指定的时间范围内发送电子邮件,它会将事件发布到 SNS 主题或通过电子邮件发送硬退回消息。
    • 抱怨:电子邮件在其电子邮件程序中被收件人归类为垃圾邮件。 投诉通知会传输到 Amazon SES,如果 Amazon SES 和 ISP 建立了反馈回路,Amazon SES 会将其转发给发件人。
    • 自动回应:收件人 ISP 将来自收件人的自动响应(例如外出通知)通知 Amazon SES,然后 Amazon SES 将通知传递给发件人。

当递送不成功时,Amazon SES 向发件人返回错误并删除电子邮件。

设置亚马逊 SES

与任何其他 AWS 服务不同,几乎不需要创建 SES 实例,因为默认情况下所有新 AWS 账户都放在 AWS SES 沙箱中。 默认情况下,每个 AWS 账户都可以在可用区域中访问 AWS SES 的沙盒。

使用沙盒模式时,我们只能向经过验证的身份发送电子邮件。 我们用来发送电子邮件的域或电子邮件地址是经过验证的身份。 我们必须构建并验证我们打算用作 From, To, Source, SenderReturn-Path 地址,然后我们才能在沙盒模式下使用 SES 发送电子邮件。 通过使用 Amazon SES 验证身份,我们可以证明我们的所有权并停止非法使用。

为避免欺诈并维护 IP 地址的声誉,AWS SES 包括电子邮件发送限制。 这些限制规定了每个用户每秒的最大电子邮件数量和每日电子邮件限制。 通过联系 AWS 支持中心,我们可以按地区设置此类配额。

让我们验证身份。 登录 AWS 控制台并搜索“亚马逊简单电子邮件服务

SES简介

然后点击“创建身份” 添加电子邮件或域以进行验证。 在我们的例子中,我们将添加一封电子邮件进行验证。

创建身份

一旦创建了身份,我们就可以验证详细信息。

创建身份

我们创建的身份进入“待验证“ 阶段。 在此阶段,用户需要查看来自 AWS 的验证邮件,并按照说明进行邮件验证。

验证身份

接下来,我们需要获取“访问键“和”密钥” 用于使用 SES 对我们的应用程序进行身份验证和授权。 为了生成它,我们需要创建一个用户组并向该组添加一个用户。 当我们创建该用户时,AWS 会生成访问密钥和秘密密钥。 所以让我们重定向到“IAM” 在 AWS 控制台中创建用户组。

创建用户组

然后我们需要添加“管理员访问” 对该组的 SES 权限。

添加权限

最后,我们将在上面的组中添加一个用户。

添加用户

接下来,我们需要选择权限组。

新增群组

最后,复制屏幕上显示的 access-key 和 secret-key 以供进一步使用。

使用 Spring Cloud 项目发送电子邮件

项目设置

让我们启动一个 Spring Cloud 项目并运行用例以与 SES 集成。 从骨架项目开始的最简单方法是通过 春季初始化:

春季初始化

我们添加了 春网 对于 REST MVC, 阿帕奇自由标记 生成基于 HTML 的电子邮件模板, Java 邮件发件人 发送电子邮件和 龙目岛 (可选的样板减少库)依赖项。 此外,我们还需要为Spring Cloud AWS和SES添加相关依赖。 对于 Spring Cloud AWS,我们将在我们的代码中添加一个单独的 Spring Cloud AWS BOM pom.xml 使用这个文件 块:

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>io.awspring.cloud</groupId>
			<artifactId>spring-cloud-aws-dependencies</artifactId>
			<version>2.3.0</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

最后,要添加对 SES 的支持,我们需要包含可作为启动模块使用的模块依赖项 spring-cloud-starter-aws-ses:

<dependency>
	<groupId>io.awspring.cloud</groupId>
	<artifactId>spring-cloud-starter-aws-ses</artifactId>
</dependency>

spring-cloud-starter-aws-ses 包括传递依赖 spring-cloud-starter-awsspring-cloud-aws-ses。 该 spring-cloud-aws-ses SES 模块包含两个类: SimpleEmailServiceMailSenderSimpleEmailServiceJavaMailSender.

  • SimpleEmailServiceMailSender 类利用 Amazon Simple Email Service 发送电子邮件。 Java Mail API 不是此实现所必需的。 它可用于发送没有附件的直接邮件消息。
  • SimpleEmailServiceJavaMailSender 类允许发送包含附件和其他 MIME 元素的电子邮件。

所以这涵盖了我们所有的基本要求!

配置 Bean

如上所述,我们需要定义两种类型的 bean: SimpleEmailServiceMailSenderSimpleEmailServiceJavaMailSender. 我们可以简单地将 access-key 和 secret-key 作为凭证​​传递并配置一个 MailSender 我们将用来发送电子邮件的 bean:

@Configuration
public class SesConfig {

    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;

    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;

    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    public AmazonSimpleEmailService amazonSimpleEmailService() {
        BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
        return AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withRegion(region)
                .build();
    }

    @Bean
    public MailSender mailSender(AmazonSimpleEmailService amazonSimpleEmailService) {
        return new SimpleEmailServiceMailSender(amazonSimpleEmailService);
    }

    @Bean
    public JavaMailSender javaMailSender(AmazonSimpleEmailService amazonSimpleEmailService) {
        return new SimpleEmailServiceJavaMailSender(amazonSimpleEmailService);
    }
}

为了发送带附件的电子邮件,我们需要配置 SimpleEmailServiceJavaMailSender 这是一个实现 JavaMailSender 来自 Spring 邮件抽象的接口。

查看我们的 Git 学习实践指南,其中包含最佳实践、行业认可的标准以及随附的备忘单。 停止谷歌搜索 Git 命令,实际上 学习 它!

我们还将定义属性以从中检索信息 application.yml:

cloud:
  aws:
    region:
      static: eu-central-1
      auto: false
    stack:
      auto: false
    credentials:
      access-key: ********
      secret-key: **************************

发送简单的电子邮件

我们可以使用发送简单的电子邮件 SimpleEmailServiceMailSender 我们上面配置的bean。 让我们定义一个服务层来使用这个 bean:

@Service
public class EmailService {

    @Autowired
    private MailSender mailSender;

    public void sendMessage(SimpleMailMessage simpleMailMessage) {
        this.mailSender.send(simpleMailMessage);
    }
}

我们正在调用 send() 中的方法 MailSender bean 来发送我们的电子邮件。 我们还需要通过 SimpleMailMessage 将包含类似的属性 from, to,我们电子邮件的文本和主题。 所以,让我们定义一个 Controller 使用 REST API 调用上述服务的类:

@RestController
public class EmailController {

    @Autowired
    private EmailService emailService;

    @PostMapping("/sendEmail")
    public String sendMessage(@RequestBody EmailDetails emailDetails) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(emailDetails.getFromEmail());
        simpleMailMessage.setTo(emailDetails.getToEmail());
        simpleMailMessage.setSubject(emailDetails.getSubject());
        simpleMailMessage.setText(emailDetails.getBody());
        emailService.sendMessage(simpleMailMessage);

        return "Email sent successfully";
    }
}

现在,如果我们运行应用程序并执行以下 curl,它将向经过验证的电子邮件地址发送一封电子邮件:

curl -i -X POST 
   -H "Content-Type:application/json" 
   -d 
'{
  "fromEmail": "[email protected]",
  "toEmail": "[email protected]",
  "subject": "test email",
  "body": "Hi, This is a test email."
}' 
 'http://localhost:8080/sendEmail'

接下来,我们可以登录收件人的邮件地址并验证收件人是否收到了电子邮件。

发送带附件的简单电子邮件

我们将定义一个服务层以将附件作为 mime 传递并设置其他电子邮件属性,例如 from, to,文字和主题:

@Service
public class EmailService {

    @Autowired
    private JavaMailSender javaMailSender;

    public void sendMessageWithAttachment(SimpleMailMessage simpleMailMessage) {

        try {
            MimeMessage message = javaMailSender.createMimeMessage();

            
            MimeMessageHelper helper = new MimeMessageHelper(
                    message,
                    MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
                    StandardCharsets.UTF_8.name());

            
            helper.addAttachment("logo.png", new ClassPathResource("logo.png"));
            helper.setTo(Objects.requireNonNull(simpleMailMessage.getTo()));
            helper.setText(Objects.requireNonNull(simpleMailMessage.getText()));
            helper.setSubject(Objects.requireNonNull(simpleMailMessage.getSubject()));
            helper.setFrom(Objects.requireNonNull(simpleMailMessage.getFrom()));
            javaMailSender.send(message);

        } catch (MessagingException e) {
            System.err.println("Exception: " + e.getMessage());
        }
    }
}

在这里我们正在使用 MimeMessageHelper 创建带有附件的电子邮件。 最后,我们将定义 Controller 层通过 SimpleMailMessage 属性:

@RestController
public class EmailController {

    @Autowired
    private EmailService emailService;

    @PostMapping("/sendEmailWithAttachment")
    public String sendMessageWithAttachment(@RequestBody EmailDetails emailDetails) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(emailDetails.getFromEmail());
        simpleMailMessage.setTo(emailDetails.getToEmail());
        simpleMailMessage.setSubject(emailDetails.getSubject());
        simpleMailMessage.setText(emailDetails.getBody());
        emailService.sendMessageWithAttachment(simpleMailMessage);

        return "Email sent successfully";
    }
}

现在,如果我们运行应用程序并执行以下 curl,它将向经过验证的电子邮件地址发送一封电子邮件:

curl -i -X POST 
   -H "Content-Type:application/json" 
   -d 
'{
  "fromEmail": "[email protected]",
  "toEmail": "[email protected]",
  "subject": "test email",
  "body": "Hi, This is a test email with attachment."
}' 
 'http://localhost:8080/sendEmailWithAttachment'

接下来,我们可以登录收件人的邮件地址并验证收件人是否收到了电子邮件。

发送带附件的模板电子邮件

我们之前看到的用例适用于开发或测试场景,但在生产中,我们通常使用带有变量的电子邮件模板,这些变量将使用 API 的响应进行替换。 我们之前添加了对 阿帕奇自由标记. 我们将使用它来定义模板并将其加载以进行处理!

为此,我们先定义一个简单的模板,命名为 email-template.ftl 放进去 templates 文件夹下 resources:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>StackAbuse Email</title>
</head>

<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
    <tr>
        <td align="center" valign="top" bgcolor="#838383"
            style="background-color: #838383;"><br> <br>
            <table width="600" border="0" cellspacing="0" cellpadding="0">
                <tr>
                    <td align="center" valign="top" bgcolor="#d3be6c"
                        style="background-color: #d3be6c; font-family: Arial,
                         Helvetica, sans-serif; font-size: 13px; color: #000000;
                          padding: 0px 15px 10px 15px;">

                        <div style="font-size: 48px; color:blue;">
                            <b>StackAbuse</b>
                        </div>

                        <div style="font-size: 24px; color: #555100;">
                            <br> Sending Email using Spring Cloud with <b>FreeMarker</b> template !!! <br>
                        </div>
                        <div>
                            <br> Want to learn a new technology or become an in-demand full-stack developer?<br>
                            <br> We teach the skills you need to level up in your career.<br>
                            <br>"Sharing knowledge is the biggest learning" <br> <br>
                            <br> <br> <b>${Name}</b><br>${location}<br>
                            <br>
                        </div>
                    </td>
                </tr>
            </table> <br> <br></td>
    </tr>
</table>
</body>
</html>

接下来,我们需要定义一个配置类来从路径加载模板并添加为bean。 为此,我们将定义 FreeMarkerConfigurationFactoryBean:

@Configuration
public class FreemarkerConfig {

    @Primary
    @Bean
    public FreeMarkerConfigurationFactoryBean factoryBean() {
        FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean();
        bean.setTemplateLoaderPath("classpath:/templates");
        return bean;
    }
}

接下来,我们将定义我们的服务层来加载此模板并创建一条最终消息以发送到 SES:

@Service
public class EmailService {
    
    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private Configuration config;
    
    public void sendTemplateMessageWithAttachment(SimpleMailMessage simpleMailMessage) {

        try {
            MimeMessage message = javaMailSender.createMimeMessage();

            
            MimeMessageHelper helper = new MimeMessageHelper(
                    message,
                    MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
                    StandardCharsets.UTF_8.name());

            Template t = config.getTemplate("email-template.ftl");
            Map model = new HashMap();
            model.put("Name", "StackAbuse Admin");
            model.put("location", "Bangalore, India");
            String html = FreeMarkerTemplateUtils.processTemplateIntoString(t, model);

            
            helper.addAttachment("logo.png", new ClassPathResource("logo.png"));
            helper.setTo(Objects.requireNonNull(simpleMailMessage.getTo()));
            helper.setText(html, true);
            helper.setSubject(Objects.requireNonNull(simpleMailMessage.getSubject()));
            helper.setFrom(Objects.requireNonNull(simpleMailMessage.getFrom()));
            javaMailSender.send(message);

        } catch (MessagingException | IOException | TemplateException e) {
            System.err.println("Exception: " + e.getMessage());
        }
    }

最后,我们将定义一个 Controller 层传递动态电子邮件属性:

@RestController
public class EmailController {

    @Autowired
    private EmailService emailService;

    @PostMapping("/sendTemplateEmailWithAttachment")
    public String sendTemplateMessageWithAttachment(@RequestBody EmailDetails emailDetails) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(emailDetails.getFromEmail());
        simpleMailMessage.setTo(emailDetails.getToEmail());
        simpleMailMessage.setSubject(emailDetails.getSubject());
        simpleMailMessage.setText(emailDetails.getBody());
        emailService.sendTemplateMessageWithAttachment(simpleMailMessage);

        return "Email sent successfully";
    }
}

现在,如果我们运行应用程序并执行以下 curl,它将向经过验证的电子邮件地址发送一封电子邮件:

curl -i -X POST 
   -H "Content-Type:application/json" 
   -d 
'{
  "fromEmail": "[email protected]",
  "toEmail": "[email protected]",
  "subject": "test email",
  "body": "Hi, This is a test template email with attachment."
}' 
 'http://localhost:8080/sendTemplateEmailWithAttachment'

接下来,我们可以登录收件人的邮件地址并验证收件人是否收到了邮件:

Freemarker 模板电子邮件

使用 AWS SES 中的模板发送个性化电子邮件

在前面的用例中,我们使用静态模板发送电子邮件。 我们如何才能针对不同目的和不同类型的收件人动态设计模板? AWS SES 允许我们创建电子邮件模板,以便在一次操作中将个性化电子邮件发送到一个或多个目的地。

我们可以为每个 Amazon SES 账户创建多达 10,000 个电子邮件模板。 每个模板的大小可达 500KB,包括文本和 HTML 部分。 我们可以在每次呼叫中发送多达 50 个目的地。

因此,让我们快速创建一个电子邮件模板。 首先,我们可以使用以下模板定义一个 JSON 文件:

{
  "Template": {
    "TemplateName": "MyTemplate",
    "SubjectPart": "Greetings from {{name}}!",
    "HtmlPart": "StackAbuse Email


StackAbuse

Sending Email using Spring Cloud with AWS SES Email template !!!

Want to learn a new technology or become an in-demand full-stack developer?

We teach the skills you need to level up in your career.

"Sharing knowledge is the biggest learning"



{{name}}
{{location}}



"
, "TextPart": "Dear {{name}},rnHere is your StackAbuse Email." } }

该模板包含以下属性:

  • 模板名称:这包含模板的名称。
  • 主题部分:这包含电子邮件的主题行。 此资产上可能存在替换标签。 这些标签的格式如下: {{tagname}}. 您可以输入一个值 {{tagname}} 发送电子邮件时针对每个目的地。
  • HTML部分:这包含电子邮件的 HTML 正文,它还可以包含替换标签。
  • 文本部分:这代表电子邮件的正文。 此版本的电子邮件将发送给其电子邮件客户端不查看 HTML 电子邮件的收件人。 此资产上可能存在替换标签。

我们可以将这个文件另存为 mytemplate.json. 最后,我们可以使用 AWS CLI 命令创建模板,如下所示:

$ aws ses create-template --cli-input-json file://mytemplate.json

接下来,让我们定义一个服务层来定义属性和发送模板电子邮件:

@Service
public class EmailService {

    @Autowired
    private AmazonSimpleEmailService simpleEmailService;

    public void sendTemplatedMessage(SimpleMailMessage simpleMailMessage) {

        Destination destination = new Destination();
        List toAddresses = new ArrayList();
        String[] emails = simpleMailMessage.getTo();
        Collections.addAll(toAddresses, Objects.requireNonNull(emails));
        destination.setToAddresses(toAddresses);

        SendTemplatedEmailRequest templatedEmailRequest = new SendTemplatedEmailRequest();
        templatedEmailRequest.withDestination(destination);
        templatedEmailRequest.withTemplate("MyTemplate");
        templatedEmailRequest.withTemplateData("{ "name":"StackAbuse Admin", "location": "Bangalore, India"}");
        templatedEmailRequest.withSource(simpleMailMessage.getFrom());
        simpleEmailService.sendTemplatedEmail(templatedEmailRequest);
    }
}

我们可以添加多个 Destination 向多个收件人发送批量电子邮件的地址。 我们正在使用 sendTemplatedEmail() 的方法 AmazonSimpleEmailService 发送此模板化电子邮件的界面。 我们还需要在我们之前创建的模板的 HTML 文本中传递要替换的替换标签。

最后,我们将定义一个 Controller 层来定义 REST API 以传递属性:

@RestController
public class EmailController {

    @Autowired
    private EmailService emailService;

    @PostMapping("/sendAWSTemplatedEmail")
    public String sendTemplatedMessage(@RequestBody EmailDetails emailDetails) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(emailDetails.getFromEmail());
        simpleMailMessage.setTo(emailDetails.getToEmail());
        simpleMailMessage.setSubject(emailDetails.getSubject());
        simpleMailMessage.setText(emailDetails.getBody());
        emailService.sendTemplatedMessage(simpleMailMessage);

        return "Email sent successfully";
    }
}

接下来,当我们运行应用程序时,我们可以执行以下操作 curl 发送模板电子邮件:

curl -i -X POST 
   -H "Content-Type:application/json" 
   -d 
'{
  "fromEmail": "[email protected]",
  "toEmail": "[email protected]",
  "subject": "Greetings from StackAbuse Admin",
  "body": "Hi, This is a AWS templated email."
}' 
 'http://localhost:8080/sendAWSTemplatedEmail'

现在收件人终于可以看到一封模板化的电子邮件了:

模板化电子邮件

请求生产访问

最后,为了向任何收件人发送电子邮件,无论收件人的地址或域是否经过验证,我们最终都必须将我们的帐户从沙箱中取出。 我们所有的身份,包括 From, Source, SenderReturn-Path 地址,仍必须进行验证。 我们可以从“帐户信息中心》页面如下:

帐户信息中心
请求生产访问

我们可以从 AWS 控制台提交填写上述所有详细信息的请求。 同样也可以使用 AWS CLI 提交。 当我们需要请求访问大量身份并希望自动化该过程时,这将很有帮助。

结论

本文涵盖了 Amazon Simple Email Service (SES) 的关键思想以及 Spring Cloud AWS 提供的与之交互的库。 此外,我们创建了一个带有 REST API 的 Spring Boot 应用程序,它可以通过 Spring Cloud AWS SES 模块发送电子邮件。

您现在应该对什么是 Amazon Simple Email Service (SES) 以及如何使用它来发送电子邮件有了深入的了解。

时间戳记:

更多来自 堆栈滥用