首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實作內嵌圖片郵件發送完整教學

     編輯:Java 相關知識

前言

在企業級應用開發中,發送包含內嵌圖片的 HTML 郵件是常見需求。本文將詳細介紹如何使用 JavaMail API、XML 模板與 MimeBodyPart 實作完整的內嵌圖片郵件發送功能,包含前端表單、後端控制器與圖片資源管理。

系統架構與流程

本範例採用經典的 MVC 架構:

  • 前端:Bootstrap 表單收集用戶資料(姓名、電話、Email、留言內容)
  • 模板層:XML 定義郵件 HTML 結構,使用 {0}~{8} 作為佔位符
  • 後端:Struts2 Action 處理表單提交,讀取 XML 模板,填充資料,組裝 MIME 郵件並發送

核心程式碼實作

1. 前端表單 (Bootstrap)

<form action="mailAction!sendMail" method="post" name="mailForm" id="mailFormId">
  <ul class="list-group">
    <li class="list-group-item">
      <div class="input-group">
        <span class="input-group-addon">姓名:</span>
        <input type="text" class="form-control" placeholder="your name" name="mailForm.name">
      </div>
    </li>
    <li class="list-group-item">
      <div class="input-group">
        <span class="input-group-addon">電話:</span>
        <input type="text" class="form-control" placeholder="your phone" name="mailForm.phone">
      </div>
    </li>
    <li class="list-group-item">
      <div class="input-group">
        <span class="input-group-addon">郵件:</span>
        <input type="text" class="form-control" placeholder="your e-mail" name="mailForm.e_mail">
      </div>
    </li>
    <li class="list-group-item">
      <span class="label label-default">留言:</span>
      <br><br>
      <textarea rows="10" name="mailForm.content" placeholder="請輸入留言(不超過 500 字)"></textarea>
    </li>
    <li class="list-group-item">
      <center><button onclick="$('#mailFormId').submit();" type="button" class="btn btn-success">發送郵件</button></center>
    </li>
  </ul>
</form>

2. XML 郵件模板

模板採用 CID (Content-ID) 方式引用內嵌圖片,cid:{4} 至 cid:{8} 對應不同圖片資源:

<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
  <html>
    <body>
      <table width="100%"><tbody><tr>
        <td><table align="center" width="600"><tbody><tr>
          <td align="center" bgcolor="#70bbd9">
            <img src="cid:{4}" alt="Creating Email Magic" width="300" height="230" />
          </td></tr><tr>
          <td bgcolor="#ffffff">
            <b>發件人: {0} <br/> 電話: {1} <br/> 郵箱: {2} <br/> 內容:<br/></b>
            <td>{3}</td>
          </tr><tr>
            <td><!-- 兩張並排圖片 -->
              <img src="cid:{5}" width="100%" height="140" />
              <img src="cid:{6}" width="100%" height="140" />
            </td>
          </tr><tr>
            <td bgcolor="#ee4c50"><!-- 社群圖示 -->
              <img src="cid:{7}" width="38" height="38" />
              <img src="cid:{8}" width="38" height="38" />
            </td>
          </tr></tbody></table></td></tr></tbody></table>
    </body>
  </html>
</xml-body>

3. XML 解析工具類

public class ReaderXML {
    public String read(String path) {
        return reader(path);
    }
    private String reader(String path) {
        SAXReader reader = new SAXReader();
        try {
            Document doc = reader.read(new File(path));
            Element root = doc.getRootElement();
            Element html = root.element("html");
            return html.asXML();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }
}

4. 郵件發送核心控制器

關鍵在於 MimeMultipart("related") 組合 HTML 內容與圖片,並透過 setHeader("Content-ID", imageName) 設定圖片唯一標識:

public class MailAction extends ActionSupport {
    private MailForm mailForm;
    
    // 建立內嵌圖片 MimeBodyPart
    private MimeBodyPart createImageMimeBodyPart(String imageName) 
            throws MessagingException, UnsupportedEncodingException {
        FileDataSource fds = new FileDataSource(
            ServletActionContext.getServletContext().getRealPath("/image") + "/" + imageName + ".gif");
        MimeBodyPart mbp = new MimeBodyPart();
        mbp.setDataHandler(new DataHandler(fds));
        mbp.setHeader("Content-ID", imageName);  // 關鍵:對應模板中的 cid:{imageName}
        mbp.setFileName(MimeUtility.encodeText(fds.getName()));
        return mbp;
    }

    public String sendMail() {
        try {
            // 1. 讀取 XML 模板並填充資料
            String xmlPath = ServletActionContext.getServletContext().getRealPath("/mailTemplate") + "/myMailTemplete.xml";
            String template = new ReaderXML().read(xmlPath);
            Object[] params = {mailForm.getName(), mailForm.getPhone(), mailForm.getE_mail(), 
                              mailForm.getContent(), "e_mail", "left", "right", "tw", "fb"};
            String htmlContent = MessageFormat.format(template, params);

            // 2. 設定郵件伺服器 (網易 163)
            Properties props = new Properties();
            props.put("mail.smtp.host", "smtp.163.com");
            props.put("mail.smtp.auth", "true");
            Session session = Session.getInstance(props);
            session.setDebug(true);

            // 3. 建立 MIME 郵件
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress("your@163.com"));
            message.setRecipient(Message.RecipientType.TO, new InternetAddress("target@qq.com"));
            message.setSubject("有人聯繫你---來自個人網站");
            message.setSentDate(new Date());

            // 4. 組裝 multipart/related 結構
            BodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent(htmlContent, "text/html;charset=gb2312");
            
            MimeMultipart multipart = new MimeMultipart("related");
            multipart.addBodyPart(htmlPart);
            // 加入 5 張內嵌圖片
            multipart.addBodyPart(createImageMimeBodyPart("e_mail"));
            multipart.addBodyPart(createImageMimeBodyPart("left"));
            multipart.addBodyPart(createImageMimeBodyPart("right"));
            multipart.addBodyPart(createImageMimeBodyPart("tw"));
            multipart.addBodyPart(createImageMimeBodyPart("fb"));
            
            message.setContent(multipart);
            message.saveChanges();

            // 5. 發送
            Transport transport = session.getTransport("smtp");
            transport.connect("smtp.163.com", "your_username", "your_password");
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
            
            return "sendMail";
        } catch (Exception e) {
            e.printStackTrace();
            return "errors";
        }
    }
}

關鍵技術點總結

  1. CID 機制:<img src="cid:xxx"> 配合 MimeBodyPart.setHeader("Content-ID", "xxx") 實現圖片內嵌
  2. multipart/related:將 HTML 內容與圖片資源關聯在同一個 MIME 實體中
  3. XML 模板分離:郵件版面與業務邏輯解耦,易於維護與修改樣式
  4. 編碼處理:中文檔名需用 MimeUtility.encodeText() 避免亂碼

常見問題排查

  • 圖片不顯示:檢查 CID 名稱是否一致、圖片路徑是否正確、Content-ID 標頭是否設定
  • 中文亂碼:確認 HTML Content-Type charset、檔名編碼、資料庫/表單編碼一致性
  • 發送失敗:驗證 SMTP 主機、端口、帳號密碼、是否開啟「授權碼」而非登入密碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved