使用 Gmail 从 Spring Boot 应用程序发送电子邮件

问题描述 投票:0回答:4

我研究了以下问题和答案: Spring Boot - 无法连接到 SMTP 主机:smtp.gmail.com,端口:25,响应:421

我想做同样的事情 - 使用 Gmail 服务器从 Spring Boot 应用程序发送电子邮件。

我的配置是这样的:

spring.mail.host = smtp.gmail.com
spring.mail.username = ***@otherdomain
spring.mail.password = ***
spring.mail.properties.mail.smtp.auth = true
spring.mail.properties.mail.smtp.starttls.enable=true 
spring.mail.properties.mail.smtp.socketFactory.port = 465
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback = false
spring.mail.properties.mail.smtp.ssl.enable = true

这是从其他问题复制的,仅根据我的需要更改了用户名和密码。我的场景唯一不同的是电子邮件地址的域名不是 gmail.com。

我的电子邮件客户端类是:

@Service
public class MailClient {

  @Autowired
  private JavaMailSender mailSender;

  public void prepareAndSend(String recipient, String message) {
    MimeMessagePreparator messagePreparator = mimeMessage -> {
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
        messageHelper.setFrom("[email protected]");
        messageHelper.setTo(recipient);
        messageHelper.setSubject("Sample mail subject");
        messageHelper.setText(message);
    };
    mailSender.send(messagePreparator);
  }
}

我的例外是:

Failed message 1: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. g78sm6788965wrd.11 - gsmtp
java email spring-boot smtp gmail
4个回答
5
投票

您可以在不重复配置的情况下执行此操作(在这种情况下

From Email
除外,但这取决于您的
SMTP
提供商):

依赖

"org.springframework.boot:spring-boot-starter-mail"

应用程序属性

spring.mail.host=smtp.gmail.com
spring.mail.port=587
[email protected]
spring.mail.password=*******
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

电子邮件服务

@Component
public class EmailService {

    private final JavaMailSender sender;

    @Autowired
    public EmailService(JavaMailSender sender) {
        this.sender = sender;
    }

    public void send(String emailTo, String subject, String body) {
        MimeMessagePreparator message = newMessage -> {
            newMessage.setRecipient(
                    Message.RecipientType.TO,
                    new InternetAddress(emailTo)
            );
            newMessage.setFrom("[email protected]");
            newMessage.setSubject(subject);
            newMessage.setText(body);
        };

        this.sender.send(message);
    }
}

4
投票

回答我自己的问题,以防其他人觉得有用:

所需的属性集是这样的:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=****
spring.mail.password=****
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

您还需要自己提供 JavaMailSender 并设置其他属性:

@Bean
public JavaMailSender getJavaMailSender() {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    mailSender.setHost("smtp.gmail.com");
    mailSender.setPort(587);

    mailSender.setUsername("***");
    mailSender.setPassword("***");

    Properties props = mailSender.getJavaMailProperties();
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.debug", "true");

    return mailSender;
}

不知道为什么我需要重复配置,但这对我有用。参考:baeldung.com


1
投票

您使用了 smtp.gmail.com,因此电子邮件应该是 gmail

编辑: 在我的 spring mvc 应用程序中,我确实喜欢这样: 服务:

import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;


    /**
         * This method will send compose and send the message
         * */
        public void sendMail(String to, String subject, String body)
        {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(to);
            message.setSubject(subject);
            message.setText(body);
            mailSender.send(message);
        }

在控制器中我使用了我的服务

applicationMailer.sendMail("*******@gmail.com", "Message from "+ userName , mailModel.getBody());

以及配置

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com"/>
        <property name="port" value="587"/>  <!--   ou 25 -->
        <property name="username" value="*****@gmail.com"/>
        <property name="password" value="******"/>
        <property name="javaMailProperties">
            <props>
                <prop key="mail.transport.protocol">smtp</prop>
                <prop key="mail.smtp.auth">true</prop>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.debug">true</prop>
            </props>
        </property>
    </bean>

0
投票

在 JavaMail 中,当您将属性“mail.smtp.starttls.enable”设置为“true”时,连接将以未加密的纯文本连接启动。连接建立后,客户端发出 STARTTLS 命令,该命令告诉服务器将连接升级为 SSL/TLS 加密。

因此,即使您的调试输出最初显示 isSSL=false,这并不意味着连接不会被加密。一旦发出 STARTTLS 命令,连接将升级到 SSL/TLS。

说明: isSSL=false:这是指初始连接,在发送 STARTTLS 命令之前是明文的。

STARTTLS:启用 STARTTLS 后,在初次握手后,通信将切换到 SSL/TLS,从而确保安全。

调试消息上下文:您看到的调试输出 (isSSL=false) 指的是 STARTTLS 升级之前的初始连接。这是预期的行为,一旦发送 STARTTLS 命令,连接将是安全的。

安全配置: 如果服务器支持 STARTTLS,您的配置是安全的。 STARTTLS命令成功执行后,通信将被加密。

为了确保 SSL/TLS: 如果您想直接使用 SSL/TLS 连接(不使用 STARTTLS),则需要设置以下属性:

Use "smtps" protocol, or explicitly define SSL socket connection settings:
props.put("mail.smtp.socketFactory.port", "465"); // SSL port
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.put("mail.smtp.port", "465");

就您而言,如果您将端口 587 与 STARTTLS 结合使用,则在执行 STARTTLS 命令后您的连接是安全的,因此您使用的配置没有问题。您通过 smtps 收到的错误(javax.net.ssl.SSLException:无法识别的 SSL 消息,纯文本连接)是因为端口 587 用于 STARTTLS,而不是用于直接 SSL/TLS(为此使用端口 465)。

结论: 是的,发出 STARTTLS 命令后,您的连接是安全的,即使调试日志最初显示 isSSL=false。

© www.soinside.com 2019 - 2024. All rights reserved.