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

Java Applet 發送 Email 兩種實作方案解析

     編輯:Java 相關知識

方案對比概覽

特性方案一:啟動郵件用戶端方案二:直接 SMTP 發送
實作複雜度極低中等
使用者體驗彈出 Foxmail/Outlook 需手動確認背景靜默發送
安全性高(用戶掌控)需處理認證、加密
適用場景簡單聯繫表單自動通知、系統郵件

方案一:mailto: 協議啟動預設郵件客戶端

核心程式碼

public class EmailApplet extends Applet {
    TextField emailField;
    Button sendBtn;
    
    public void init() {
        setLayout(new BorderLayout());
        emailField = new TextField();
        sendBtn = new Button("sendMail");
        add("North", emailField);
        add("South", sendBtn);
    }
    
    public boolean action(Event e, Object arg) {
        if ("sendMail".equals(arg)) {
            try {
                String mailto = emailField.getText();  // 格式: mailto:user@domain?subject=...&body=...
                URL url = new URL(mailto);
                getAppletContext().showDocument(url);  // 瀏覽器處理 mailto: 協議
            } catch (Exception ex) {
                System.out.println(ex);
            }
        }
        return true;
    }
}

mailto: URL 格式範例

mailto:recipient@example.com?subject=Hello&body=Message%20content
mailto:user1@domain.com,user2@domain.com?cc=cc@domain.com&bcc=bcc@domain.com

優缺點分析

  • ✅ 零伺服器端依賴,無需 SMTP 設定
  • ✅ 利用用戶已登入的郵件客戶端,避開認證難題
  • ❌ 需用戶裝有郵件客戶端且關聯 mailto: 協議
  • ❌ 無法附加檔案(部分客戶端支援 attachment 參數但非標準)
  • ❌ 無法追蹤發送狀態

方案二:Socket 直連 SMTP 伺服器

核心流程

  1. 建立 Socket 連線至 SMTP 埠(預設 25,SSL 465,STARTTLS 587)
  2. 發送 SMTP 指令序列:HELO → MAIL FROM → RCPT TO → DATA → 郵件內容 → . → QUIT
  3. 解析伺服器回應碼(2xx 成功、4xx 暫時失敗、5xx 永久失敗)

關鍵程式碼片段

void sendMail() {
    String sender = txtFrom.getText();   // from@domain.com
    String recipient = txtTo.getText();  // to@domain.com
    String content = txtBody.getText();
    
    // 簡易郵箱格式驗證
    if (!sender.contains("@") || !recipient.contains("@")) {
        showError("郵件格式錯誤");
        return;
    }
    
    try (Socket socket = new Socket(smtpHost, SMTP_PORT);
         PrintStream out = new PrintStream(socket.getOutputStream());
         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
        
        // 讀取歡迎訊息
        System.out.println(in.readLine());
        
        // SMTP 對話
        out.println("HELO " + senderHost);
        System.out.println(in.readLine());
        
        out.println("MAIL FROM:<" + senderName + ">");
        System.out.println(in.readLine());
        
        out.println("RCPT TO:<" + recipientName + ">");
        System.out.println(in.readLine());
        
        out.println("DATA");
        System.out.println(in.readLine());
        
        out.println("Subject: Test from Applet");
        out.println("From: " + sender);
        out.println("To: " + recipient);
        out.println("");  // 空行分隔標頭與內文
        out.println(content);
        out.println(".");  // 結束標記
        System.out.println(in.readLine());
        
        out.println("QUIT");
        showSuccess("郵件發送成功");
        
    } catch (Exception e) {
        showError("發送失敗: " + e.getMessage());
    }
}

關鍵技術細節與坑點

1. SMTP 協議細節

  • 指令結尾必須 \r\n(PrintStream.println() 自動處理)
  • DATA 後內文以單獨一行 . 結束
  • 內文中若出現單獨 . 行需轉義為 ..

2. 編碼與 MIME

原始碼僅支援純文字。中文需採用 MIME 編碼:

out.println("Content-Type: text/plain; charset=UTF-8");
out.println("Content-Transfer-Encoding: base64");
out.println();
out.println(Base64.getEncoder().encodeToString(content.getBytes("UTF-8")));

3. 認證機制(現代 SMTP 必須)

// AUTH LOGIN 流程
out.println("AUTH LOGIN");
readResponse();  // 334 VXNlcm5hbWU6
out.println(Base64.getEncoder().encodeToString(username.getBytes()));
readResponse();  // 334 UGFzc3dvcmQ6
out.println(Base64.getEncoder().encodeToString(password.getBytes()));
readResponse();  // 235 Authentication successful

4. SSL/TLS 加密

// 隱式 SSL (Port 465)
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket socket = factory.createSocket(smtpHost, 465);

// 顯式 STARTTLS (Port 587)
Socket socket = new Socket(smtpHost, 587);
// ... 傳送 STARTTLS 指令後升級為 SSLSocket

現代化替代方案

Applet 技術已淘汰,現代 Web 應用建議:

  • 後端發送:前端呼叫 REST API,後端使用 JavaMail/Jakarta Mail 發送
  • Email 服務商 API:SendGrid、Mailgun、Amazon SES、Postmark
  • 前端直接發送:EmailJS、SMTP.js(僅限靜態網站,需暴露憑證風險)

JavaMail 標準庫範例(後端推薦)

Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
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);
    }
});

Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
msg.setSubject(subject);
msg.setText(body);
Transport.send(msg);

總結

方案一適合簡單「聯繫我們」表單,零後端成本;方案二展示 SMTP 底層協議但缺乏認證、加密、MIME 等生產級功能。現代開發請務必使用成熟郵件庫或雲端服務,避免重複造輪子並踩安全坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved