英文:
Java Email is sent with no content and not attachment when sending email from WSO2
问题
It seems like you're encountering an issue with sending emails with attachments using WSO2 class mediator. The exception you're seeing, "javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed," suggests a problem with handling the attachment data type.
To resolve this issue, you can try adding the following code, which you mentioned in your "EDIT" section:
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
mc.addMailcap("multipart/report;; x-java-content-handler=com.sun.mail.dsn.multipart_report");
mc.addMailcap("message/delivery-status;; x-java-content-handler=com.sun.mail.dsn.message_deliverystatus");
mc.addMailcap("message/disposition-notification;; x-java-content-handler=com.sun.mail.dsn.message_dispositionnotification");
mc.addMailcap("text/rfc822-headers;; x-java-content-handler=com.sun.mail.dsn.text_rfc822headers");
This code configures the MailcapCommandMap to handle various MIME types correctly, which might help resolve the issue you're facing.
After adding this code, please try sending the email again and see if it resolves the problem.
英文:
I am trying to send email from WSO2 class mediator, when sending the email with no attachment it works fine but when sending with attachment I get the following exception:
javax.mail.MessagingException: IOException while sending message;
nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
I am using micro-integrator 4.1.0
The java code to send the email with attachment is as follows:
emailHostSMTPs = getConfig("email.host.smtps");
emailHostSMTP = getConfig("email.host.smtp");
emailProtocol = getConfig("email.protocol");
senderEmail = getConfig("email.sender");
senderPassword = Encryptor.decrypt(getConfig("email.password"));
senderUser = getConfig("email.sender.user");
emailPort = getConfig("email.port");
MimeMultipart multipart = new MimeMultipart();
Authenticator authenticator = new SMTPAuthenticator();
MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory();
MimeBodyPart bodyPart = new MimeBodyPart();
String html = "";
Properties props = System.getProperties();
props.put("mail.transport.protocol", emailProtocol);
props.put("mail.smtp.host", emailHostSMTP);
props.put("mail." + emailProtocol + ".auth", "true");
props.put("mail.smtp.port", emailPort);
sslSocketFactory.setTrustAllHosts(true);
props.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
Session session = Session.getInstance(props, authenticator);
html = "<html><body dir='rtl' style='font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;'> "
+ emailBody + " </body></html>";
bodyPart.setContent(html, "text/html; charset=UTF-8");
multipart.addBodyPart(bodyPart);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(senderEmail, fromDisplayName));
message.setReplyTo(new Address[] { new InternetAddress(fromEmail) });
if (toList != null && toList.size() > 0) {
for (String to : toList) {
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
}
} else {
throw new Exception("List of users to send email to is empty");
}
if (ccList != null && ccList.size() > 0) {
for (String cc : ccList) {
message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc));
}
}
if (bccList != null && bccList.size() > 0) {
for (String bcc : bccList) {
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(bcc));
}
}
MimeBodyPart mimeBodyPart = new PreencodedMimeBodyPart("base64");
mimeBodyPart.setContent(fileDataStrBase64, "application/*");
mimeBodyPart.setFileName(MimeUtility.encodeText(fileName, "utf-8", "B"));
multipart.addBodyPart(mimeBodyPart);
message.setSubject(subject, "UTF-8");
message.setContent(multipart);
message.setSentDate(new Date());
Transport transport = session.getTransport(emailProtocol);
transport.connect(senderEmail, senderPassword);
transport.sendMessage(message, message.getAllRecipients());
My class mediator is deployed as jar file inside MI_HOME/lib
jars used:
- javax.mail-1.6.2.jar
- activation-1.1.1.jar
JDK Version : 11.0.8
EDIT:
After adding the following code (from another post) the email is sent but I get no email content and no attachment just subject !
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
mc.addMailcap("multipart/report;; x-java-content-handler=com.sun.mail.dsn.multipart_report");
mc.addMailcap("message/delivery-status;; x-java-content-handler=com.sun.mail.dsn.message_deliverystatus");
mc.addMailcap("message/disposition-notification;; x-java-content-handler=com.sun.mail.dsn.message_dispositionnotification");
mc.addMailcap("text/rfc822-headers;; x-java-content-handler=com.sun.mail.dsn.text_rfc822headers");
Below is the mail debug:
DEBUG: failed to load any providers, using defaults
DEBUG: Tables of loaded providers from javamail.providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle,1.6.2], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle,1.6.2], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle,1.6.2], com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle,1.6.2], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle,1.6.2], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle,1.6.2]}
DEBUG: Providers Listed By Protocol: {imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle,1.6.2], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle,1.6.2], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle,1.6.2], imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle,1.6.2], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle,1.6.2], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle,1.6.2]}
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle,1.6.2]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=mail.mydomain.com, user=myemail, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "mail.mydomain.com", port 587, isSSL false
220 MyMailServer Microsoft ESMTP MAIL Service ready at Sun, 28 May 2023 14:33:31 +0300
DEBUG SMTP: connected to host "mail.mydomain.com", port: 587
EHLO host.docker.internal
250-MyMailServer Hello [10.x.x.x]
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "41943040"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
STARTTLS
220 2.0.0 SMTP server ready
EHLO host.docker.internal
250-MyMailServer Hello [10.x.x.x]
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH GSSAPI NTLM LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "41943040"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "AUTH", arg "GSSAPI NTLM LOGIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: protocolConnect login, host=mail.mydomain.com, user=mysenderemail, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:<mysenderemail@mydomin.com>
250 2.1.0 Sender OK
RCPT TO:<myemail@mydomin.com>
250 2.1.5 Recipient OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: myemail@mydomin.com
DATA
354 Start mail input; end with <CRLF>.<CRLF>
Date: Sun, 28 May 2023 14:33:31 +0300 (AST)
From: mysenderemail@mydomin.com
To: myemail@mydomin.com
Message-ID: <1628804451.7.1685273611450@host.docker.internal>
Subject: test attachment localhost 2.24
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_6_2147206188.1685273611445"
.
250 2.6.0 <1628804451.7.1685273611450@host.docker.internal> [InternalId=91379724192809, Hostname=MyMailServer2] 1339 bytes in 0.293, 4.462 KB/sec Queued mail for delivery
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 2.0.0 Service closing transmission channel
答案1
得分: 2
以下是您提供的Java代码的中文翻译:
package org.ycr;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class MailSend extends AbstractMediator {
public boolean mediate(MessageContext context) {
log.info("开始发送邮件");
// 存储当前线程的类加载器,以便稍后恢复它。
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
String host = "smtp.gmail.com";
int port = 587;
final String username = "xxxx@gmail.com";
final String password = "xxxx";
final String atachmentFilePath = "/home/xx/xx/xxxx/log.txt";
final String toAddress = "xxxx@gmail.com";
// 设置一个新的类加载器,以便Javax能够找到Mime依赖项。
Thread.currentThread().setContextClassLoader(javax.mail.Message.class.getClassLoader());
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
// 创建一个新消息
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress));
message.setSubject("邮件示例");
Multipart multipart = new MimeMultipart();
// 创建HTML正文部分
MimeBodyPart htmlPart = new MimeBodyPart();
String htmlContent = "<h1>示例</h1>"
+ "<p>这是一封示例邮件</p>";
htmlPart.setContent(htmlContent, "text/html");
// 将HTML正文部分添加到多部分消息中
multipart.addBodyPart(htmlPart);
// 文件附件
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(atachmentFilePath);
// 将附件部分添加到多部分消息中
multipart.addBodyPart(attachmentPart);
// 将消息的内容设置为多部分消息
message.setContent(multipart);
Transport.send(message);
log.info("邮件发送完成");
return true;
}catch (Exception e){
handleException("发生错误。", context);
}finally {
Thread.currentThread().setContextClassLoader(classLoader);
}
return true;
}
}
希望这有助于您理解代码的中文翻译。如果您有任何其他问题,请随时提出。
英文:
Here is a working Class Mediator to send Emails with a body and an attachment. I tested this on JDK 8. This should work with JavaX dependencies on JDK 11 as well.
package org.ycr;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class MailSend extends AbstractMediator {
public boolean mediate(MessageContext context) {
log.info("Starting Main sending");
// Storing the current class loader of the thread, so we can restore it later.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
String host = "smtp.gmail.com";
int port = 587;
final String username = "xxxx@gmail.com";
final String password = "xxxx";
final String atachmentFilePath = "/home/xx/xx/xxxx/log.txt";
final String toAddress = "xxxx@gmail.com";
// Setting a new class loader so Javax is able to find the Mime dependencies.
Thread.currentThread().setContextClassLoader(javax.mail.Message.class.getClassLoader());
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
// Create a new message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress));
message.setSubject("Email Sample");
Multipart multipart = new MimeMultipart();
// Create the HTML body part
MimeBodyPart htmlPart = new MimeBodyPart();
String htmlContent = "<h1>Sample</h1>"
+ "<p>This is an Sample Mail</p>";
htmlPart.setContent(htmlContent, "text/html");
// Add the HTML body part to the multipart message
multipart.addBodyPart(htmlPart);
// File attaching
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(atachmentFilePath);
// Add the attachment part to the multipart message
multipart.addBodyPart(attachmentPart);
// Set the content of the message to the multipart message
message.setContent(multipart);
Transport.send(message);
log.info("Done sending Email");
return true;
}catch (Exception e){
handleException("Error occurred.", context);
}finally {
Thread.currentThread().setContextClassLoader(classLoader);
}
return true;
}
}
On a side note, I'm not sure why you are trying this with a class mediator, but you can do the same without the class mediator as well. Either by using the Email COnnector or by using Email Transport.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论