我正在创建一个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();
}
我没有得到任何错误,一切都编译得很好。我只是没有收到任何电子邮件。如果有人能够帮助,我将非常感谢。
答案 0 :(得分:6)
Runtime.exec(String)
不会通过将整个字符串粘贴到UNIX shell并运行它来执行它。这是因为它是一个巨大的安全漏洞。
想象一下你这样做了:
runtime.exec("Hello "+name+" | mail ...");
然后,我可以将name
设置为; rm -rf /*; echo
或&& cat /etc/passwd
,或其他一些shell注入代码。
所以,Java is breaking up your command into parts:
更准确地说,命令字符串使用由调用new StringTokenizer(命令)创建的StringTokenizer分解为标记,而不进一步修改字符类别。然后,由tokenizer生成的标记以相同的顺序放置在新的字符串数组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);
}
}
答案 1 :(得分:3)
为什么不使用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;
}
答案 2 :(得分:1)
因为你没有产生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