使用JavaMail在电子邮件中嵌入图像
我想使用javamail发送带有内嵌图像的电子邮件。
我正在做这样的事情。
MimeMultipart content = new MimeMultipart("related"); BodyPart bodyPart = new MimeBodyPart(); bodyPart.setContent(message, "text/html; charset=ISO-8859-1"); content.addBodyPart(bodyPart); bodyPart = new MimeBodyPart(); DataSource ds = new ByteArrayDataSource(image, "image/jpeg"); bodyPart.setDataHandler(new DataHandler(ds)); bodyPart.setHeader("Content-Type", "image/jpeg; name=image.jpg"); bodyPart.setHeader("Content-ID", ""); bodyPart.setHeader("Content-Disposition", "inline"); content.addBodyPart(bodyPart); msg.setContent(content);
我也试过了
bodyPart.setHeader("inline; filename=image.jpg");
和
bodyPart.setDisposition("inline");
但无论如何,图像都作为附件发送,内容处理正在变成“附件”。
如何使用javamail在电子邮件中内联发送图像?
你的问题
据我所知,它看起来像你创建消息的方式,一切都是正确的! 您使用正确的MIME类型和所有内容。
我不确定为什么你使用DataSource和DataHandler,并在图像上有ContentID,但是你需要为我完成你的问题才能解决更多问题。 特别是,以下行:
bodyPart.setContent(message, "text/html; charset=ISO-8859-1");
消息是什么? 它包含吗?
您是否尝试使用String cid = ContentIdGenerator.getContentId();
生成ContentID String cid = ContentIdGenerator.getContentId();
而不是使用image
资源
这篇博客文章教我如何使用正确的消息类型,附加我的图像并参考HTML正文中的附件: 如何使用Java发送带有嵌入式图像的电子邮件
细节
信息
您必须使用MimeMultipart
类创建内容。 使用字符串"related"
作为构造函数的参数非常重要,告诉JavaMail您的部件是“一起工作” 。
MimeMultipart content = new MimeMultipart("related");
内容标识符
您需要生成ContentID,它是一个字符串,用于标识您附加到电子邮件中的图像,并从电子邮件正文中引用它。
String cid = ContentIdGenerator.getContentId();
注意:此ContentIdGenerator
类是假设的。 您可以创建一个或内联创建内容ID。 在我的例子中,我使用一个简单的方法:
import java.util.UUID; // ... String generateContentId(String prefix) { return String.format("%s-%s", prefix, UUID.randomUUID()); }
HTML正文
HTML代码是MimeMultipart
内容的一部分。 使用MimeBodyPart
类。 设置该部分的文本时,不要忘记指定encoding
和"html"
!
MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setText("" + "" + " " + " Here is my image:
" + " " + " " + "" ,"US-ASCII", "html"); content.addBodyPart(htmlPart);
请注意,作为图像的来源,我们使用cid:
和生成的ContentID。
图片附件
我们可以为图像的附件创建另一个MimeBodyPart
。
MimeBodyPart imagePart = new MimeBodyPart(); imagePart.attachFile("resources/teapot.jpg"); imagePart.setContentID("<" + cid + ">"); imagePart.setDisposition(MimeBodyPart.INLINE); content.addBodyPart(imagePart);
请注意,我们在<
和>
之间使用相同的ContentID,并将其设置为图像的ContentID。 我们还将处置设置为INLINE
以表示此图像要显示在电子邮件中,而不是作为附件显示。
完成消息
而已! 如果您在正确的会话上创建SMTP消息并使用该内容,则您的电子邮件将包含嵌入的图像! 例如:
SMTPMessage m = new SMTPMessage(session); m.setContent(content); m.setSubject("Mail with embedded image"); m.setRecipient(RecipientType.TO, new InternetAddress("your@email.com")); Transport.send(m)
如果这对您有用,请告诉我! ;)
你为什么不尝试这样的东西?
MimeMessage mail = new MimeMessage(mailSession); mail.setSubject(subject); MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(message, "text/html"); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); messageBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(new File("complete path to https://stackoverflow.com/questions/2996514/inline-images-in-email-using-javamail/image.jpg")); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(fileAttachment.getName()); messageBodyPart.setDisposition(MimeBodyPart.INLINE); multipart.addBodyPart(messageBodyPart); mail.setContent(multipart);
在消息中,有一个标签,你应该没问题。
祝你好运
这对我有用:
MimeMultipart rootContainer = new MimeMultipart(); rootContainer.setSubType("related"); rootContainer.addBodyPart(alternativeMultiPartWithPlainTextAndHtml); // not in focus here rootContainer.addBodyPart(createInlineImagePart(base64EncodedImageContentByteArray)); ... message.setContent(rootContainer); message.setHeader("MIME-Version", "1.0"); message.setHeader("Content-Type", rootContainer.getContentType()); ... BodyPart createInlineImagePart(byte[] base64EncodedImageContentByteArray) throws MessagingException { InternetHeaders headers = new InternetHeaders(); headers.addHeader("Content-Type", "image/jpeg"); headers.addHeader("Content-Transfer-Encoding", "base64"); MimeBodyPart imagePart = new MimeBodyPart(headers, base64EncodedImageContentByteArray); imagePart.setDisposition(MimeBodyPart.INLINE); imagePart.setContentID("<image>"); imagePart.setFileName("http://sofzh.miximages.com/java/image.jpg"); return imagePart;
如果您使用的是Spring,请使用MimeMessageHelper
发送带内联内容的电子邮件( 参考资料 )。
如果您使用的是Spring Boot ,请创建JavaMailSender bean或通过向application.properties文件添加相应的属性来配置它。
@Bean public JavaMailSender getJavaMailSender() { JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); mailSender.setHost(host); mailSender.setPort(port); mailSender.setUsername(username); mailSender.setPassword(password); Properties props = mailSender.getJavaMailProperties(); props.put("mail.transport.protocol", "smtp"); props.put("mail.smtp.auth", authEnable); props.put("mail.smtp.starttls.enable", starttlsEnable); //props.put("mail.debug", "true"); mailSender.setJavaMailProperties(props); return mailSender; }
创建算法以生成唯一的CONTENT-ID
import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Random; public class ContentIdGenerator { static int seq = 0; static String hostname; public static void getHostname() { try { hostname = InetAddress.getLocalHost().getCanonicalHostName(); } catch (UnknownHostException e) { // we can't find our hostname? okay, use something no one else is // likely to use hostname = new Random(System.currentTimeMillis()).nextInt(100000) + ".localhost"; } } /** * Sequence goes from 0 to 100K, then starts up at 0 again. This is large * enough, * and saves * * @return */ public static synchronized int getSeq() { return (seq++) % 100000; } /** * One possible way to generate very-likely-unique content IDs. * * @return A content id that uses the hostname, the current time, and a * sequence number * to avoid collision. */ public static String getContentId() { getHostname(); int c = getSeq(); return c + "." + System.currentTimeMillis() + "@" + hostname; } }
使用内联发送电子邮件。
@Autowired private JavaMailSender javaMailSender; public void sendEmailWithInlineImage() { MimeMessage mimeMessage = null; try { InternetAddress from = new InternetAddress(from, personal); mimeMessage = javaMailSender.createMimeMessage(); mimeMessage.setSubject("Test Inline"); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom(from); helper.setTo("test@test.com"); String contentId = ContentIdGenerator.getContentId(); String htmlText = "Hello, This is test with email inlines.
"; helper.setText(htmlText, true); ClassPathResource classPathResource = new ClassPathResource("static/images/first.png"); helper.addInline(contentId, classPathResource); javaMailSender.send(mimeMessage); } catch (Exception e) { LOGGER.error(e.getMessage()); } }
使用以下代码段:
MimeBodyPart imgBodyPart = new MimeBodyPart(); imgBodyPart.attachFile("Image.png"); imgBodyPart.setContentID('<'+"i01@example.com"+'>'); imgBodyPart.setDisposition(MimeBodyPart.INLINE); imgBodyPart.setHeader("Content-Type", "image/png"); multipart.addBodyPart(imgBodyPart);
您不需要内联和基本编码 – 您可以传统地附加链接并将链接添加到主消息的text/html
类型的text/html
。
但是请记住在附加到主消息之前(在附加文件之后)将imgBodyPart
的标题的Content-Type
为image/jpg
左右。
以下是完整的代码
import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; private BodyPart createInlineImagePart() { MimeBodyPart imagePart =null; try { ByteArrayOutputStream baos=new ByteArrayOutputStream(10000); BufferedImage img=ImageIO.read(new File(directory path,"sdf_email_logo.jpg")); ImageIO.write(img, "jpg", baos); baos.flush(); String base64String=Base64.encode(baos.toByteArray()); baos.close(); byte[] bytearray = Base64.decode(base64String); InternetHeaders headers = new InternetHeaders(); headers.addHeader("Content-Type", "image/jpeg"); headers.addHeader("Content-Transfer-Encoding", "base64"); imagePart = new MimeBodyPart(headers, bytearray); imagePart.setDisposition(MimeBodyPart.INLINE); imagePart.setContentID("<sdf_email_logo>"); imagePart.setFileName("sdf_email_logo.jpg"); } catch(Exception exp) { logError("17", "Logo Attach Error : "+exp); } return imagePart; } MimeMultipart mp = new MimeMultipart(); //mp.addBodyPart(createInlineImagePart()); mp.addBodyPart(createInlineImagePart()); String body=""
messageBodyPart.setContent(htmlText,“text / html”); multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart(); DataSource fds = new FileDataSource("resources/Images/bday.jpg"); messageBodyPart.setDataHandler(new DataHandler(fds)); messageBodyPart.setHeader("Content-ID", ""); // add image to the multipart multipart.addBodyPart(messageBodyPart); msg.setContent(multipart); Transport.send(msg);