【问题标题】:Embedded images not showing in email from Javamail html templateJavamail html模板的电子邮件中未显示嵌入的图像
【发布时间】:2025-11-24 19:40:01
【问题描述】:

我已经成功地遵循了如何使用 javamail 将图像嵌入 HTML 的教程。但是我现在正尝试从模板 html 文件中读取,然后在发送之前将图像嵌入其中。

我确信代码在我使用时适合嵌入图像:

bodyPart.setContent("<html><body><h2>A title</h2>Some text in here<br/>" +
               "<img src=\"cid:the-img-1\"/><br/> some more text<img src=\"cid:the-img-1\"/></body></html>", "text/html");

图像显示正常。但是,当我使用以下文件读取文件时:

readHTMLToString reader = new readHTMLToString();
String str = reader.readHTML();  
bodyPart.setContent(str, "text/html");

发送电子邮件时图像不显示。

我将html读取为字符串的代码如下:

public class readHTMLToString {
static String finalFile;

public static String readHTML() throws IOException{

//intilize an InputStream
    File htmlfile = new File("C:/temp/basictest.html");
    System.out.println(htmlfile.exists());
try {
  FileInputStream fin = new FileInputStream(htmlfile);

  byte[] buffer= new byte[(int)htmlfile.length()];
new DataInputStream(fin).readFully(buffer);
    fin.close();
    String s = new String(buffer, "UTF-8");
    finalFile = s;
}
catch(FileNotFoundException e)
{
  System.out.println("File not found" + e);
}
catch(IOException ioe)
{
  System.out.println("Exception while reading the file " + ioe);
}
return finalFile;
  }
}

我发送邮件的完整类如下:

package com.bcs.test;

import java.io.IOException;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class SendEmail {

public static void main(String[] args) throws IOException {

    final String username = "usernamehere@gmail.com";
    final String password = "passwordhere";

    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.port", "587");


    Session session = Session.getInstance(props,
      new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
      });

    try {

        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("from-email@gmail.com"));
        message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse("recepientemailhere"));
        message.setSubject("Testing Subject");

        //SET MESSAGE AS HTML
        MimeMultipart multipart = new MimeMultipart("related");  

        // Create bodypart.  
        BodyPart bodyPart = new MimeBodyPart();  

        // Create the HTML with link to image CID.  
        // Prefix the link with "cid:". 

        //bodyPart.setContent("<html><body><h2>A title</h2>Some text in here<br/>" +
              // "<img src=\"cid:the-img-1\"/><br/> some more text<img src=\"cid:the-img-1\"/></body></html>", "text/html");
        readHTMLToString reader = new readHTMLToString();
        String str = reader.readHTML();  

        // Set the MIME-type to HTML.  
        bodyPart.setContent(str, "text/html");  

        // Add the HTML bodypart to the multipart.  
        multipart.addBodyPart(bodyPart);  

        // Create another bodypart to include the image attachment.  
        BodyPart imgPart = new MimeBodyPart();  

        // Read image from file system.  
        DataSource ds = new FileDataSource("C:\\temp\\dice.png");  
        imgPart.setDataHandler(new DataHandler(ds));  

        // Set the content-ID of the image attachment.  
        // Enclose the image CID with the lesser and greater signs. 
        imgPart.setDisposition(MimeBodyPart.INLINE);
        imgPart.setHeader("Content-ID","the-img-1");
        //bodyPart.setHeader("Content-ID", "<image_cid>");  

        // Add image attachment to multipart.  
        multipart.addBodyPart(imgPart);  

        // Add multipart content to message.  
        message.setContent(multipart);  



        //message.setText("Dear Mail Crawler,"
        //  + "\n\n No spam to my email, please!");

        Transport.send(message);

        System.out.println("Done");

    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }
}
}

我已经阅读了许多关于此的答案,但真的不确定为什么会发生这种情况。我认为这是因为我的 html 文件存在问题,但是我使用与上面初始 setContent 代码相同的内容创建了一个非常基本的文件,并且图片没有出现在这个基本示例中。

与读入字节数组有关吗?

非常感谢任何帮助。

谢谢

【问题讨论】:

    标签: java html jakarta-mail


    【解决方案1】:

    电子邮件客户端解释 HTML 代码的方式不同于写入 HTML 模板文件。但是您可以确定的一件事是,一旦您获得模板,将图像的字节数组复制到 src 属性。您可以尝试使用内联图像作为浏览器解释 src 属性并发出另一个请求以获取数据。

    让您更深入地了解这个概念。Inline Images in HTML

    【讨论】:

    • 感谢您的快速回复,但我不完全确定我完全理解您的回答。澄清一下,如果我只是将 html 文件中的文本读入字符串,为什么会有不同的解释?您能否举一个有关将图像的字节数组复制到 src 属性的示例。谢谢你
    【解决方案2】:

    当然,您需要确保文件中的数据实际上是用 UTF-8 编码的,而不是您计算机的默认编码。如果您使用所有 ASCII 文本对此进行测试,则无关紧要。

    假设文件中的文本与上面示例代码中的字符串中的文本相同,您可以比较两种情况(字符串、文件)以查看 JavaMail 发送的消息如何通过使用 message.writeTo(新文件输出流(“msg.txt”));就在 Transport.send 调用之前或位置。

    【讨论】:

    • 您好比尔,感谢您的建议。 html模板中的编码确实是UTF-8。当我将消息写入 .txt 时,html 似乎是相同的,但在它之后是图像的 base64 代码,在它之前是消息属性:` ------=_Part_0_21357269.1334981436511 Content-Type: text/ html; charset=us-ascii Content-Transfer-Encoding: 7bit`
    • 我不确定你在说什么。只是为了检查一下,您在两种情况下都使用相同的代码来构造消息,唯一的区别在于您如何设置主要消息正文部分的内容,对吗?如果您可以发布 msg.txt 文件的两个版本,这可能会有所帮助。