JHipster MailService——javax.mail。SendFailedException:没有收件人地址

时间:2021-10-07 18:13:33

UPDATE: Hello Guys,

更新:你好,

I was finally able to resolve this problem by changing how I added a recipient. Not sure why this works as opposed to the boiler plate but this allowed me to pass this hurdle. Hope this provides help to those experiencing similar issues.

我终于能够通过改变添加收件人的方式来解决这个问题。我不知道为什么这和锅炉板相反,但这让我能通过这个障碍。希望这能为那些遇到类似问题的人提供帮助。

@Async
public void sendEmail(String to, String sendFrom, String subject, String content) {
    log.debug("Send e-mail to '{}' with subject '{}' and content={}",
            to, subject, content);

    // Prepare message using a Spring helper
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    try {
        mimeMessage.setRecipients(Message.RecipientType.TO, to);
        mimeMessage.setContent(content, MediaType.TEXT_HTML_VALUE);
        mimeMessage.setFrom(new InternetAddress(sendFrom));
        mimeMessage.setSubject(subject);

        javaMailSender.send(mimeMessage);
        log.debug("Sent e-mail to '{}'", to);
    } catch (Exception e) {
        log.warn("E-mail could not be sent to '{}', exception is: {}", to, e.getMessage());
    }
}

ORIGINAL POST

最初的发布

After several days of researching and reaching out to more senior developers I know, I am finally coming here for help. Any input or help is greatly appreciated!

经过几天的研究和接触,我知道,我终于来这里寻求帮助了。任何输入或帮助都非常感谢!

I'm using the MailService provided with the JHipster stack.

我使用的是JHipster栈提供的邮件服务。

The application is using my personal email. It has 2 step authentication so I do not need to allow less secure apps as I'm directly giving my app a password through app passwords. IMAP and POP are enabled.

应用程序正在使用我的个人电子邮件。它有两个步骤的认证,所以我不需要允许不太安全的应用程序,因为我直接给我的应用程序一个密码通过应用程序的密码。启用IMAP和POP。

From what I can tell I am able to connect correctly, I just can't send to a recipient. I have tried different emails at different domains with no luck. If I change the app password to my raw password it complains saying it must use an app specific password. So This leads me to be sure I'm authenticating/connecting correctly.

从我能说的我能正确连接,我就是不能发送给收件人。我在不同的领域尝试过不同的邮件,但都没有运气。如果我将应用程序密码更改为我的原始密码,它会抱怨说它必须使用一个特定的密码。这使我确信我正在正确地验证/连接。

Pulling sources and debugging brought me to doSend in the JavaMailSenderImpl and the error specifically is thrown by mimeMessage.getAllRecipients()

拉源和调试使我在JavaMailSenderImpl中做了doSend,而错误是由mimemessage.getall接收者()抛出的

My console shows:

我的控制台将显示:

[DEBUG] com.myapp.aop.logging.LoggingAspect - Enter: com.myapp.service.MailService.sendEmail() with argument[s] = [myemail@gmail.com, myemail@gmail.com, hi, false, true]
[DEBUG] com.myapp.service.MailService - Send e-mail[multipart 'false' and html 'true'] to 'myemail@gmail.com' with subject 'subjecthi' and content=hi
[DEBUG] com.sun.mail.smtp - useEhlo true, useAuth true
[DEBUG] com.sun.mail.smtp - trying to connect to host "smtp.gmail.com", port 587, isSSL false
[DEBUG] com.sun.mail.smtp - connected to host "smtp.gmail.com", port: 587

[DEBUG] com.sun.mail.smtp - Found extension "SIZE", arg "35882577"
[DEBUG] com.sun.mail.smtp - Found extension "8BITMIME", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "STARTTLS", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "ENHANCEDSTATUSCODES", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "PIPELINING", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "CHUNKING", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "SMTPUTF8", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "SIZE", arg "35882577"
[DEBUG] com.sun.mail.smtp - Found extension "8BITMIME", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN XOAUTH"
[DEBUG] com.sun.mail.smtp - Found extension "ENHANCEDSTATUSCODES", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "PIPELINING", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "CHUNKING", arg ""
[DEBUG] com.sun.mail.smtp - Found extension "SMTPUTF8", arg ""
[DEBUG] com.sun.mail.smtp - Attempt to authenticate using mechanisms: LOGIN     PLAIN DIGEST-MD5 NTLM 
[WARN] com.myapp.service.MailService - E-mail could not be sent to user     'myemail@gmail.com', exception is: Failed messages:     javax.mail.SendFailedException: No recipient addresses
[DEBUG] com.myapp.aop.logging.LoggingAspect - Exit:     com.myapp.service.MailService.sendEmail() with result = null

I am providing the following files:

我提供以下文件:

  • application.yml
  • application.yml
  • MailConfiguration.java
  • MailConfiguration.java
  • MailService.java
  • MailService.java
  • call from my OrderResource.java to the MailService
  • OrderResource打来的电话。java的MailService

application.yml

application.yml

# Disable the spring security default configuration from spring-boot-actuator
management.security.enabled: true
security.basic.enabled: false

# Disable Jolokia - An http/json bridge for remote JMX access
endpoints.jolokia.enabled: false

# security configuration (this key should be unique for your application, and kept secret)
jhipster.security.rememberme.key: securitykey

StripeSecretApiKey: mystripekey

async:
    corePoolSize: 2
    maxPoolSize: 50
    queueCapacity: 10000

mail:
    host: smtp.gmail.com
    port: 587
    username: myemail@gmail.com
    password: myapppassword
    protocol: smtp
    tls: true
    auth: true
    from: mydomainemail@gmail.com

authentication:
    oauth:
        clientid: mydomainapp
        secret: mysecret
        # Token is valid 2 hours
        tokenValidityInSeconds: 7200

swagger:
    title: mydomain API
    description: mydomain applications and beyond!
    termsOfServiceUrl: http://jhipster.github.io/
    contact:
    license: Apache 2.0
    licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.html

OrderResource.java call to mail service

OrderResource。java调用邮件服务。

mailService.sendEmail("myemail@gmail.com", "subject hi", "hi",false, true);

MailConfiguration.java

MailConfiguration.java

package com.myapp.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
public class MailConfiguration implements EnvironmentAware {

    private static final String ENV_SPRING_MAIL = "mail.";
    private static final String DEFAULT_HOST = "127.0.0.1";
    private static final String PROP_HOST = "host";
    private static final String DEFAULT_PROP_HOST = "localhost";
    private static final String PROP_PORT = "port";
    private static final String PROP_USER = "username";
    private static final String PROP_PASSWORD = "password";
    private static final String PROP_PROTO = "protocol";
    private static final String PROP_TLS = "tls";
    private static final String PROP_AUTH = "auth";
    private static final String PROP_SMTP_AUTH = "mail.smtp.auth";
    private static final String PROP_STARTTLS = "mail.smtp.starttls.enable";
    private static final String PROP_TRANSPORT_PROTO =         "mail.transport.protocol";

    private final Logger log = LoggerFactory.getLogger(MailConfiguration.class);

    private RelaxedPropertyResolver propertyResolver;

    @Override
    public void setEnvironment(Environment environment) {
    this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_SPRING_MAIL);
    }

    @Bean
    public JavaMailSenderImpl javaMailSender() {
        log.debug("Configuring mail server");
    String host = propertyResolver.getProperty(PROP_HOST, DEFAULT_PROP_HOST);
    int port = propertyResolver.getProperty(PROP_PORT, Integer.class, 0);
    String user = propertyResolver.getProperty(PROP_USER);
    String password = propertyResolver.getProperty(PROP_PASSWORD);
    String protocol = propertyResolver.getProperty(PROP_PROTO);
    Boolean tls = propertyResolver.getProperty(PROP_TLS, Boolean.class, false);
    Boolean auth = propertyResolver.getProperty(PROP_AUTH, Boolean.class, false);

    JavaMailSenderImpl sender = new JavaMailSenderImpl();
    if (host != null && !host.isEmpty()) {
        sender.setHost(host);
    } else {
        log.warn("Warning! Your SMTP server is not configured. We will try to use one on localhost.");
        log.debug("Did you configure your SMTP settings in your application.yml?");
        sender.setHost(DEFAULT_HOST);
    }

    sender.setPort(port);
    sender.setUsername(user);
    sender.setPassword(password);

    Properties sendProperties = new Properties();
    sendProperties.setProperty(PROP_SMTP_AUTH, auth.toString());
    sendProperties.setProperty(PROP_STARTTLS, tls.toString());
    sendProperties.setProperty(PROP_TRANSPORT_PROTO, protocol);
    sender.setJavaMailProperties(sendProperties);
    return sender;
   }
}

MailService.java

MailService.java

package com.myapp.service;

import com.myapp.domain.User;
import org.apache.commons.lang.CharEncoding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring4.SpringTemplateEngine;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.mail.Message;
import javax.mail.SendFailedException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Locale;

/**
 * Service for sending e-mails.
 * <p/>
 * <p>
 * We use the @Async annotation to send e-mails asynchronously.
 * </p>
 */
@Service
public class MailService {

    private final Logger log = LoggerFactory.getLogger(MailService.class);

    @Inject
    private Environment env;

    @Inject
    private JavaMailSenderImpl javaMailSender;

    @Inject
    private MessageSource messageSource;

    @Inject
    private SpringTemplateEngine templateEngine;

    /**
     * System default email address that sends the e-mails.
     */
    private String from;

    @PostConstruct
    public void init() {
        this.from = env.getProperty("mail.from");
    }

    @Async
    public void sendEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) {
        log.debug("Send e-mail[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}",
            isMultipart, isHtml, to, subject, content);

        // Prepare message using a Spring helper
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, isMultipart, CharEncoding.UTF_8);
            message.setTo(to);
            message.setFrom(from);
            message.setSubject(subject);
            message.setText(content, isHtml);
            javaMailSender.send(message.getMimeMessage());
            log.debug("Sent e-mail to User '{}'", to);
        } catch (Exception e) {
            log.warn("E-mail could not be sent to user '{}', exception is: {}", to, e.getMessage());
        }
    }

    @Async
    public void sendPurchaseEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) {
        log.debug("Send e-mail[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}",
        isMultipart, isHtml, to, subject, content);

        // Prepare message using a Spring helper
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, isMultipart, CharEncoding.UTF_8);
            message.setTo(to);
            message.setFrom(from);
            message.setSubject(subject);
            message.setText(content, isHtml);
            javaMailSender.send(message.getMimeMessage());
            log.debug("Sent purchase e-mail to '{}'", to);
        } catch (Exception e) {
            log.warn("E-mail could not be sent to '{}', exception is: {}", to, e.getMessage());
        }
    }

    @Async
    public void sendActivationEmail(User user, String baseUrl) {
        log.debug("Sending activation e-mail to '{}'", user.getEmail());
        Locale locale = Locale.forLanguageTag(user.getLangKey());
        Context context = new Context(locale);
        context.setVariable("user", user);
        context.setVariable("baseUrl", baseUrl);
        String content = templateEngine.process("activationEmail", context);
        String subject = messageSource.getMessage("email.activation.title", null, locale);
        sendEmail(user.getEmail(), subject, content, false, true);
    }

    @Async
    public void sendPurchaseNotificationEmail(String orderId, String email, String baseUrl) {
        log.debug("Sending activation e-mail to '{}'", email);
        Locale locale = Locale.forLanguageTag(Locale.ENGLISH.getLanguage());

        String title = messageSource.getMessage("email.purchase.title", null, locale);

        Context context = new Context(locale);
        context.setVariable("orderId", orderId);
        context.setVariable("baseUrl", baseUrl);
        context.setVariable("subject", title);
        context.setVariable("greeting", messageSource.getMessage("email.purchase.greeting", null, locale));
        context.setVariable("text1", messageSource.getMessage("email.purchase.text1", null, locale));
        context.setVariable("text2", messageSource.getMessage("email.purchase.text2", null, locale));
        context.setVariable("signature", messageSource.getMessage("email.purchase.signature", null, locale));

        String content = templateEngine.process("purchaseEmail", context);
        sendPurchaseEmail(email, title, content, false, true);
    }
}

1 个解决方案

#1


1  

Another Update: Today I stumbled upon this post which enlightened me to a one line addition mimeMessage.saveChanges() that appears to resolve my previous issue. Kudos to @dkar for his answer that finally rectified this issue for me as well. Read his answer here: Original Answer

另一个更新:今天我无意中发现了这篇文章,它启发了我添加了一段添加了mimeMessage.saveChanges()的文章,它似乎解决了我之前的问题。@dkar为他的回答,最后也为我纠正了这个问题。阅读他的答案:原始答案。

@Async
public void sendEmail(String to, String sendFrom, String subject, String content) {
    log.debug("Send e-mail to '{}' with subject '{}' and content={}",
            to, subject, content);

    // Prepare message using a Spring helper
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    try {
        MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, CharEncoding.UTF_8);
        message.setTo(to);
        message.setFrom(sendFrom);
        message.setSubject(subject);
        message.setText(content, true);
        mimeMessage.saveChanges();
        javaMailSender.send(message.getMimeMessage());
        log.debug("Sent e-mail to User '{}'", to);
    } catch (Exception e) {
        log.warn("E-mail could not be sent to user '{}', exception is: {}", to, e.getMessage());
    }
}

#1


1  

Another Update: Today I stumbled upon this post which enlightened me to a one line addition mimeMessage.saveChanges() that appears to resolve my previous issue. Kudos to @dkar for his answer that finally rectified this issue for me as well. Read his answer here: Original Answer

另一个更新:今天我无意中发现了这篇文章,它启发了我添加了一段添加了mimeMessage.saveChanges()的文章,它似乎解决了我之前的问题。@dkar为他的回答,最后也为我纠正了这个问题。阅读他的答案:原始答案。

@Async
public void sendEmail(String to, String sendFrom, String subject, String content) {
    log.debug("Send e-mail to '{}' with subject '{}' and content={}",
            to, subject, content);

    // Prepare message using a Spring helper
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    try {
        MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, CharEncoding.UTF_8);
        message.setTo(to);
        message.setFrom(sendFrom);
        message.setSubject(subject);
        message.setText(content, true);
        mimeMessage.saveChanges();
        javaMailSender.send(message.getMimeMessage());
        log.debug("Sent e-mail to User '{}'", to);
    } catch (Exception e) {
        log.warn("E-mail could not be sent to user '{}', exception is: {}", to, e.getMessage());
    }
}