簡體   English   中英

Java Runtime.exec()不從命令行發送電子郵件

[英]Java Runtime.exec() not sending emails as from the command line

我正在創建一個java應用程序,我想添加的一個功能是將生成的電子郵件發送給用戶。 我在Macbook上設置了郵件,我可以從命令行發送電子郵件。 我在調用runtime.exec()時發送電子郵件時遇到問題。 任何人都知道為什么它不會執行和發送電子郵件?

Runtime runtime = Runtime.getRuntime();

try {
    runtime.exec("echo This is the body | mail -s Subject -F myemail@gmail.com");
}
catch ( Exception e ) {

    // TODO Auto-generated catch block
    e.printStackTrace();
}

我沒有得到任何錯誤,一切都編譯得很好。 我只是沒有收到任何電子郵件。 如果有人能夠幫助,將非常感謝謝謝。

Runtime.exec(String)不會通過將其粘貼到UNIX shell並運行它來執行整個字符串。 這是因為它是一個巨大的安全漏洞。

想象一下你這樣做了:

runtime.exec("Hello "+name+" | mail ...");

然后我可以設置name ; rm -rf /*; echo ; rm -rf /*; echo ; rm -rf /*; echo&& cat /etc/passwd ,或其他一些shell注入代碼。

因此, Java正在將您的命令分解為多個部分

更確切地說,命令字符串使用由調用new StringTokenizer(命令)創建的StringTokenizer分解為標記,而不進一步修改字符類別。 然后,由標記化器生成的標記以相同的順序放置在新的字符串數組cmdarray中。

最終,您將單獨運行echo命令,其參數如| mail echo命令只會將這些輸出打印到您不收集的標准輸出。 它永遠不會調用mail命令。

由於涉及安全風險,您不應使用mail命令從Java發送郵件。 您應該使用JavaMail包,它提供了一個安全方便的API來發送郵件。 UNIX mail命令通過連接到端口25上本地計算機上運行的sendmail守護程序來工作,JavaMail也可以這樣做。

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

public class SendMail {
    public static sendMail(String from, String to, String subject, String body)
        throws MessagingException
    {
        final Properties p = new Properties();
        p.put("mail.smtp.host", "localhost");
        final Message msg = new MimeMessage(Session.getDefaultInstance(p));
        msg.setFrom(new InternetAddress(from));
        msg.addRecipient(RecipientType.TO, new InternetAddress(to));
        msg.setSubject(subject);
        msg.setText(body);
        Transport.send(msg);
    }
}

你為什么不使用JavaMail

用法示例:

private boolean sendMail(String host, String port, String user, String password,  List<String> toList, String htmlBody, String subject) {
    Properties props = System.getProperties();
    props.put("mail.smtp.user", user);
    props.put("mail.smtp.password", password);
    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");
    props.put("mail.smtp.EnableSSL.enable", "true");

    Session session = Session.getInstance(props, null);

    MimeMessage message = new MimeMessage(session);
    try {

        message.setFrom(new InternetAddress(user));

        // To get the array of addresses
        for (String to : toList) {
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(to));
        }

        message.setSubject(subject);
        message.setContent(htmlBody, "text/html");

        Transport transport = session.getTransport("smtp");
        try {
            transport.connect(host, user, password);
            transport.sendMessage(message, message.getAllRecipients());
        } finally {
            transport.close();
        }

    } catch (Exception e) {
        return false;
    } 
    return true;
}

因為你沒有產生shell和| 是一個shell功能。 一個有效的例子:

創建一個shell腳本並將命令數組傳遞給exec()。

class Test {
  public static void main(String[] args) {
    try {
      Runtime runtime = Runtime.getRuntime();
      String[] cmd = { "sh", "send.sh", "This is the body", "Subject", "myemail@gmail.com"};
      runtime.exec(cmd);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Shell腳本:

echo $1 | mail -s $2 -F $3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM