Java MIME类型多部分/混合的无对象DCH
我正在使用Play框架和apache common email+freemarker开发一个应用程序。 使用此选项,我遇到了一个问题,每当我发送电子邮件时,我都会看到以下错误消息: javax.mail.MessagineException:发送消息时发生IOException; 嵌套异常为:javax.activation.UnsupportedDataTypeException:否 MIME类型多部分/混合的对象DCH 以下是电子邮件堆栈:Java MIME类型多部分/混合的无对象DCH,java,apache,email,playframework,freemarker,Java,Apache,Email,Playframework,Freemarker,我正在使用Play框架和apache common email+freemarker开发一个应用程序。 使用此选项,我遇到了一个问题,每当我发送电子邮件时,我都会看到以下错误消息: javax.mail.MessagineException:发送消息时发生IOException; 嵌套异常为:javax.activation.UnsupportedDataTypeException:否 MIME类型多部分/混合的对象DCH 以下是电子邮件堆栈: package service.email;
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);
}
}
package service.email;
导入com.google.common.base.Strings;
导入freemarker.template.Configuration;
导入freemarker.template.template;
导入freemarker.template.TemplateException;
导入freemarker.template.TemplateExceptionHandler;
导入org.apache.commons.mail.DefaultAuthenticator;
导入org.apache.commons.mail.Email附件;
导入org.apache.commons.mail.EmailException;
导入org.apache.commons.mail.ImageHtmlEmail;
导入play.Logger;
导入utils.ConfigurationUtils;
导入utils.enums.EmailTemplates;
导入javax.activation.CommandMap;
导入javax.activation.MailcapCommandMap;
导入javax.inject.inject;
导入javax.inject.Singleton;
导入java.io.IOException;
导入java.io.StringWriter;
导入java.io.Writer;
导入java.util.List;
导入java.util.Locale;
导入java.util.Map;
导入java.util.concurrent.CompletableFuture;
导入java.util.concurrent.CompletionStage;
导入静态java.util.Objects.nonNull;
导入静态utils.enums.ConfigurationKey.*;
@独生子女
公共类电子邮件服务{
@注入
私人MarkerService MarkerService;
@注入
专用配置utils配置utils;
私人图像HTMLEMAIL电子邮件;
私有最终配置Freemarker配置;
私有最终字符串TemplatePrefix;
来自的私有最终字符串;
私有最终字符串重写;
@注入
公共电子邮件服务(ConfigurationUtils ConfigurationUtils){
this.configurationUtils=configurationUtils;
freemarkerConfiguration=新配置();
freemarkerConfiguration.setDefaultEncoding(“UTF-8”);
freemarkerConfiguration.setLocale(Locale.FRANCE);
freemarkerConfiguration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW\u HANDLER);
templatePrefixPath=configurationUtils.getString(电子邮件\u模板\u路径);
from=configurationUtils.getString(电子邮件发送自);
overrideTo=configurationUtils.getString(电子邮件\u OVERRIDE\u TO);
}
/**
*@param to
*@param电子邮件模板
*@param电子邮件附件
*@返回完成阶段
*@EmailException
*@抛出异常
*@throws-TemplateException
*/
public CompletionStage发送(字符串收件人、EmailTemplates emailTemplate、地图数据、,
列出电子邮件(附件){
试一试{
Logger.info(“[EmailService]生成电子邮件:\n\t发送到{}\n\t使用的模板:{}\n”,发送到,emailTemplate.getFileName());
ImageHtmlEmail电子邮件=新的ImageHtmlEmail();
setHostName(configurationUtils.getString(email_HOSTNAME));
email.setSmtpPort(configurationUtils.getInt(email_SMPT_PORT));
setAuthenticator(新的DefaultAuthenticator(configurationUtils.getString(电子邮件\用户名)、configurationUtils.getString(电子邮件\密码));
email.setssonconnect(configurationUtils.getBoolean(email_SSL_ENABLED));
//这在开发模式下很有用,您可以通过提供“to”属性将所有电子邮件重定向到单个收件人
email.addTo(Strings.isNullOrEmpty(overrideTo)?to:overrideTo);
email.setFrom(from);
email.setSubject(emailTemplate.getSubject());
Logger.info(“[EmailService]正在准备freemarker绑定…”);
Template Template=freemarkerConfiguration.getTemplate(templatePrefixPath+emailTemplate.getFileName());
编写器stringWriter=新的stringWriter();
流程模板(数据、stringWriter);
stringWriter.flush();
stringWriter.close();
email.setHtmlMsg(stringWriter.toString());
setTextMsg(“您的电子邮件客户端不支持HTML消息”);
Logger.info(“[EmailService]附加文件…”);
if(非空(电子邮件附件)){
用于(电子邮件附件电子邮件附件:电子邮件附件){
电子邮件。附件(电子邮件附件);
}
}
Logger.info(“[EmailService]发送电子邮件…”);
email.send();
}捕获(EmailException | IOException | TemplateException e){
//TODO:按类型管理异常
e、 printStackTrace();
Logger.debug(“发送电子邮件时出错…\n”);
}
返回CompletableFuture.completedFuture(空);
}
public CompletionStage发送(字符串收件人、EmailTemplates emailTemplate、地图数据){
返回发送(收件人、emailTemplate、数据、空);
}
}
模板:
<html>
<head>
<title>Test</title>
</head>
<body>
${URL_RESET_PASSWORD}
</body>
</html>
试验
${URL\u重置\u密码}
这个问题困扰了我一个星期了。。。我真的不明白为什么会出现错误,我只知道DCH是空的,DCH工厂也是空的。我最终找到的解决方案:
CompletableFuture.runAsync(() -> {
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
email.send();
} catch (final EmailException e) {
throw new RuntimeException(e);
}
}, Executors.newSingleThreadExecutor());
dch为null,因为当前的类加载器为null。不起作用。已经完成。fyi multipart/mixed或multipart/alternative不起作用,但text/html起作用