有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

MIME类型多部分/混合的java无对象DCH

我正在使用Play框架和apache common email+freemarker开发一个应用程序。 使用此选项,我遇到了一个问题,每当我发送电子邮件时,我都会看到以下错误消息:

javax.mail.MessagingException: IOException while sending message; nested exception is: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed

以下是电子邮件堆栈:

package service.email;


import com.google.common.base.Strings;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.ImageHtmlEmail;
import play.Logger;
import utils.ConfigurationUtils;
import utils.enums.EmailTemplates;

import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

import static java.util.Objects.nonNull;
import static utils.enums.ConfigurationKey.*;

@Singleton
public class EmailService {

  @Inject
  private MarkerService markerService;
  @Inject
  private ConfigurationUtils configurationUtils;

  private ImageHtmlEmail email;
  private final Configuration freemarkerConfiguration;
  private final String templatePrefixPath;
  private final String from;
  private final String overrideTo;

  @Inject
  public EmailService(ConfigurationUtils configurationUtils) {
    this.configurationUtils = configurationUtils;
    freemarkerConfiguration = new Configuration();

    freemarkerConfiguration.setDefaultEncoding("UTF-8");
    freemarkerConfiguration.setLocale(Locale.FRANCE);
    freemarkerConfiguration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

    templatePrefixPath = configurationUtils.getString(EMAIL_TEMPLATES_PATH);
    from = configurationUtils.getString(EMAIL_FROM);
    overrideTo = configurationUtils.getString(EMAIL_OVERRIDE_TO);


  }

  /**
   * @param to
   * @param emailTemplate
   * @param emailAttachments
   * @return CompletionStage<Void>
   * @throws EmailException
   * @throws IOException
   * @throws TemplateException
   */
  public CompletionStage<Void> send(String to, EmailTemplates emailTemplate, Map<String, String> datas,
                                    List<EmailAttachment> emailAttachments) {
    try {
      Logger.info("[EmailService] Building email :\n\tSent to {}\n\tTemplate used : {}\n", to, emailTemplate.getFileName());
      ImageHtmlEmail email = new ImageHtmlEmail();
      email.setHostName(configurationUtils.getString(EMAIL_HOSTNAME));
      email.setSmtpPort(configurationUtils.getInt(EMAIL_SMPT_PORT));
      email.setAuthenticator(new DefaultAuthenticator(configurationUtils.getString(EMAIL_USERNAME), configurationUtils.getString(EMAIL_PASSWORD)));
      email.setSSLOnConnect(configurationUtils.getBoolean(EMAIL_SSL_ENABLED));
      // This is useful in dev mode, you can redirect all emails to a single recipient by supplying the 'to' attribute
      email.addTo(Strings.isNullOrEmpty(overrideTo) ? to : overrideTo);
      email.setFrom(from);
      email.setSubject(emailTemplate.getSubject());

      Logger.info("[EmailService] Preparing freemarker binding...");
      Template template = freemarkerConfiguration.getTemplate(templatePrefixPath + emailTemplate.getFileName());
      Writer stringWriter = new StringWriter();
      template.process(datas, stringWriter);
      stringWriter.flush();
      stringWriter.close();
      email.setHtmlMsg(stringWriter.toString());
      email.setTextMsg("Your email client does not support HTML messages");
      Logger.info("[EmailService] attaching files...");
      if (nonNull(emailAttachments)) {
        for (EmailAttachment emailAttachment : emailAttachments) {
          email.attach(emailAttachment);
        }
      }
      Logger.info("[EmailService] Sending email...");
      email.send();
    } catch (EmailException | IOException | TemplateException e) {
      // TODO : Manage exception by type
      e.printStackTrace();
      Logger.debug("Error While sending email...\n");
    }
    return CompletableFuture.completedFuture(null);
  }

  public CompletionStage<Void> send(String to, EmailTemplates emailTemplate, Map<String, String> datas) {
    return send(to, emailTemplate, datas, null);
  }
}

模板:

<html>
<head>
    <title>Test</title>
</head>
<body>
 ${URL_RESET_PASSWORD}
</body>
</html>

这个问题困扰了我一个星期了。。。我真的不明白为什么会出现错误,我只知道DCH为null,DCH工厂也为null


共 (1) 个答案

  1. # 1 楼答案

    我最终找到的解决方案:

      CompletableFuture.runAsync(() -> {
        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
        try {
          email.send();
        } catch (final EmailException e) {
          throw new RuntimeException(e);
        }
      }, Executors.newSingleThreadExecutor());
    

    dch为null,因为当前的类装入器为null