让 Spring Boot 应用程序通过 AWS SES 发送简单电子邮件需要哪些配置步骤?

Posted

技术标签:

【中文标题】让 Spring Boot 应用程序通过 AWS SES 发送简单电子邮件需要哪些配置步骤?【英文标题】:What is the required configuration steps to have a Spring Boot application send simple e-mails via AWS SES? 【发布时间】:2018-02-24 23:57:32 【问题描述】:

我今天已经为此奋斗了几个小时。我从http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_sending_mails 的文档开始,它并没有真正说明具体步骤。它只是说开发人员可以包含一个 Bean XML,然后自动装配MailSender。我已经尝试了许多变体,但无法使用 spring-cloud-aws 让它工作。我终于求助于直接包含 aws-java-sdk-ses 并手动配置类。

这是一个简单的项目,展示了我的尝试: https://github.com/deinspanjer/aws-ses-test

这个项目可以编译,但是当我运行它时,我得到:

Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because @ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'
- Bean method 'simpleMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
- Bean method 'javaMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'

如果我尝试添加 javax-mail (https://github.com/deinspanjer/aws-ses-test/tree/try-with-javax-mail-api),则错误变为:

Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.JndiNameProperty @ConditionalOnProperty (spring.mail.jndi-name) did not find property 'jndi-name'; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.HostProperty @ConditionalOnProperty (spring.mail.host) did not find property 'host'
- Bean method 'simpleMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
- Bean method 'javaMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'

如果相反,我尝试显式添加对 aws-java-sdk-ses (https://github.com/deinspanjer/aws-ses-test/tree/try-with-aws-java-sdk-ses) 的依赖项,则会收到此错误:

Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because @ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'
- Bean method 'javaMailSender' in 'MailSenderAutoConfiguration' not loaded because @ConditionalOnClass did not find required class 'javax.mail.Session'
- Bean method 'simpleMailSender' in 'MailSenderAutoConfiguration' not loaded because @ConditionalOnMissingClass found unwanted class 'org.springframework.cloud.aws.mail.simplemail.SimpleEmailServiceJavaMailSender'

对于这个错误,我尝试在@Autowired 中添加@Qualifier("simpleMailSender") 注释,但没有帮助。

我希望有人能够引导我朝着正确的方向前进。

【问题讨论】:

您似乎缺少在 AwsSesTestApplication 类上导入 @ImportResource("/aws-mail.xml")。 我只是尝试将该注释添加到应用程序类,但它不会更改错误消息。 【参考方案1】:

前段时间我在一个 Spring Boot Web 项目中使用了 AWS SES,但我还没有使用 Spring Cloud AWS 将我的应用程序与邮件服务集成。

相反,我只是将spring-boot-starter-mail 包含在项目依赖项(pom.xml)中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

然后我在application.properties 中设置 SMTP 服务器参数。就我而言,我使用了这些属性:

spring.mail.host=email-smtp.eu-west-1.amazonaws.com
spring.mail.port=465
spring.mail.protocol=smtps
spring.mail.smtps.auth=true
spring.mail.smtp.ssl.enable=true
spring.mail.username=<my-user>
spring.mail.password=<my-password>

注意:服务器主机和端口可能不同。

Spring Boot 将创建一个默认的 JavaMailSender 实例,并使用 previos 参数对其进行配置。您可以使用此对象发送电子邮件...

这可能不是 AWS SES 与 Spring Boot 应用程序集成的最佳方法,但它对我来说很好。

【讨论】:

我也想过这样做,但我想避免对 SES 使用 smtp 接口。不过感谢您的意见,很可能它可能会帮助其他人。 @deinspanjer 为什么要避免使用 SMTP? (仅供参考...) 因为亚马逊建议尽可能使用 SES API,主要是出于性能考虑。请参阅本文档部分开头的注释:cloud.spring.io/spring-cloud-static/spring-cloud-aws/… 看看这个 Gist:gist.github.com/ShigeoTejima/f2997f57405010c3caca 它可能有用... 是的,我确实看到了这一点,它帮助我开始,但正如评论者所说,自发布以来 API 似乎发生了变化,并且无法正常工作盒子了。【参考方案2】:
    将 AWS-Java-sdk 添加到您的项目中 在您的机器上设置 AWS 凭证(密钥) 创建发送电子邮件请求 SendEmailRequest#.sendEmail(request)

附言您在这里不需要任何 JavaMail。你可以用任何想要的方式将它包装到 Spring 中的 bean 中。

【讨论】:

谢谢你,我想我应该更清楚一点,我是专门寻求帮助 spring-cloud-aws 工作的,如我的示例项目所示。【参考方案3】:

您可以尝试以下步骤来解决您的问题。我在您的forked repo 中尝试了这些更改,它对我有用。

    pom.xml 文件中添加依赖项“com.amazonaws:aws-java-sdk-ses”。 创建一个自动配置类来配置邮件发件人 bean。下面是例子。 AWSCredentialsProviderspring-cloud-starter-aws 开箱即用配置和提供。

.

@Configuration
public class SimpleMailAutoConfig 

    @Bean
    public AmazonSimpleEmailService amazonSimpleEmailService(AWSCredentialsProvider credentialsProvider) 
        return AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(credentialsProvider)
                // Replace US_WEST_2 with the AWS Region you're using for
                // Amazon SES.
                .withRegion(Regions.US_WEST_2).build();
    

    @Bean
    public MailSender mailSender(AmazonSimpleEmailService ses) 
        return new SimpleEmailServiceMailSender(ses);
    

3。使用spring API使用配置的邮件发件人发送邮件。

希望对你有帮助。

编辑:

如果您需要使用JavaMailSender 而不是MailSender(例如当您要发送附件时),只需配置SimpleEmailServiceJavaMailSender 而不是SimpleEmailServiceMailSender

像这样:

    @Bean
    public JavaMailSender mailSender(AmazonSimpleEmailService ses) 
        return new SimpleEmailServiceJavaMailSender(ses);
    

【讨论】:

能否请您协助使用JavaMailSender 而不是MailSender 定义邮件发送器bean?我正在尝试使用 SES 发送 HTML 电子邮件。但是MailSender 只允许纯文本电子邮件。如何将此 SES 配置指定为 JavaMailSender 什么是SimpleEmailServiceMailSender?我找不到这门课。 这个类来自库github.com/spring-cloud/spring-cloud-aws。您可以参考 fork repo 中的 pom.xml 以获取依赖项 需要什么spring boot版本?另外我怎样才能获得 MailSender 依赖项? 你可以参考 fork 仓库中的 pom.xml。我认为是 1.5.x。【参考方案4】:

您也可以通过 Application.properties 来完成。确保您不在 AWS SES 的沙盒中。

    验证您的电子邮件地址或域以通过 SES 发送电子邮件。转到 SES DashBoard 并选择“电子邮件地址”。(为了测试,您可以从 SES DashBoard 发送演示电子邮件--> 电子邮件地址 --> 发送测试电子邮件)。 创建“访问密钥 ID”和“秘密访问密钥”。(如果没有此密钥,您将无法发送邮件。您将收到 535 错误)。

3.现在将密钥放入您的 application.properties。如下图

`spring.mail.host=email-smtp.us-east-1.amazonaws.com(Your Hosting region)
spring.mail.username=<Access Key Id>
spring.mail.password=<Secret access key>`

如果您使用 MimeMessage,请设置发送邮件 ID,如下所示:

MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom("yourmailID@yourDomain.com");

希望对你有帮助。

【讨论】:

【参考方案5】:

只是为了在@davioooh 答案中添加一些内容,如果有人使用 aws 的 smtp 接口而不是 aws sdk api,-- 如果您使用端口 465,则使用协议作为 smtps 但是,如果您使用端口 25,587,那么您使用协议作为 smtp 这是强制性的。

如果你在使用 465 端口时没有使用 SMTPS,那么你的 springboot 应用程序会出现异常。(因为,使用 465 端口时客户端必须在传输邮件时启动 TLS,所以你必须在你的application.properties 文件。

同样,您在使用端口 25,587 时不需要使用 SMTPS,因为在这种情况下,服务器首先响应客户端是否启用了 tls,然后客户端启动 tls 加密。因此,您只需使用 SMTP在端口 25,587 的情况下。

【讨论】:

以上是关于让 Spring Boot 应用程序通过 AWS SES 发送简单电子邮件需要哪些配置步骤?的主要内容,如果未能解决你的问题,请参考以下文章

AWS Fargate 无法通过负载均衡器/公共 IP 访问 dockerized spring boot 应用程序

通过 Maven 为 Spring Boot 应用程序创建 AWS Beanstalk 的 .ebextensions 的正确方法是啥

在 AWS Elastic BeanStalk 上运行的 Spring Boot 应用程序中配置 AWS RDS

S3 中的 Spring Boot 配置 - AWS beanstalk

Spring Boot 在 AWS EC2 上自动关闭

索引页面不起作用,但 api 适用于 AWS beanstalk Spring Boot