Java 邮件 API 路由电子邮件而不修改 FROM header
Java Mail API route emails without modifying the FROM header
我有 2 个电子邮件地址,我想将我的所有邮件从一个电子邮件地址路由(自动转发)到另一个电子邮件地址。不幸的是,我的邮件客户端上的这个功能停止工作了,我想创建一个小型控制台应用程序来检查我的电子邮件并每 10 分钟自动转发一次。
我开始在 Java 中使用 Java 邮件 API 开发控制台应用程序,但我在设置适当的 FROM header 时遇到问题。当我设置原始发件人电子邮件地址并尝试发送电子邮件时,SMTP 抛出异常:SMTP mail FROM does not match authenticated user name
.
它合乎逻辑,因为这样我可以伪造电子邮件地址发件人,但我不希望电子邮件像我发送的那样出现在另一封电子邮件中。出于多种原因需要这样做:
- 更容易阅读
- 当我想回复电子邮件时,我希望能够回复我的原始发件人而不是我自己
我已经使用 PHP 在我的网站联系表单上实现了这一点,但我不知道如何在 Java 中做到这一点。
我会尽量用更简单的方式解释情况。
我发送了 2 封电子邮件:a@a.com
和 b@b.com
现在电子邮件从 c@c.com
发送到 a@a.com
我想将电子邮件从 a@a.com
转发到 b@b.com
,但是当邮件到达 FROM header 中的 b@b.com
时,我想看到它来了来自 c@c.com
(不是来自 a@a.com
)
我的问题是:这是否可能,如果可能,我如何将 header FROM 设置为原始发件人。
这是我的代码:
public class ForwardMailService {
public static void forward() {
String popHost = "pop.a.com";
String popPort = "110"; // 995 SSL
String imapHost = "imap.a.com";
String imapPort = "143"; // 993 SSL
String smtpHost = "smtp.a.com";
String smtpPort = "25";
String user = "USERNAME";
String password = "PASSWORD";
Properties properties = new Properties();
properties.put("mail.store.protocol", "imap");
properties.put("mail.imap.host", imapHost);
properties.put("mail.imap.port", imapPort);
properties.put("mail.imap.starttls.enable", "true");
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.host", smtpHost);
properties.put("mail.smtp.port", smtpPort);
Session session = Session.getDefaultInstance(properties);
try {
Store store = session.getStore("imap");
store.connect(imapHost, user, password);
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_ONLY);
SearchTerm searchTerm = new SentDateTerm(ComparisonTerm.GE, new Date());
Message[] messages = folder.search(searchTerm);
if(messages.length != 0) {
for(Message message : messages) {
String from = InternetAddress.toString(message.getFrom());
String replyTo = InternetAddress.toString(message.getReplyTo());
String to = InternetAddress.toString(message.getRecipients(Message.RecipientType.TO));
String subject = message.getSubject();
Date sentDate = message.getSentDate();
Message forward = new MimeMessage(session);
forward.setRecipients(Message.RecipientType.TO, InternetAddress.parse("a@a.com));
forward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.setReplyTo(InternetAddress.parse(replyTo));
MimeBodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
messageBodyPart.setContent(message, "message/rfc822");
multipart.addBodyPart(messageBodyPart);
forward.setContent(multipart);
forward.saveChanges();
Transport transport = session.getTransport("smtp");
try {
transport.connect(smtpHost, user, password);
transport.sendMessage(forward, forward.getRecipients(Message.RecipientType.TO));
} catch(Exception ex) {
ex.printStackTrace();
} finally {
transport.close();
}
}
}
folder.close(false);
store.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
提前致谢。
这完全取决于您的邮件服务器是否允许您向 b@b.com 发送邮件而不显示它来自 a@a.com。大多数服务器不允许这样做。
一个更简单的解决方案是从 a@a.com 的收件箱中读取邮件并使用 Folder.appendMessages 将其附加到 b@b.com 的收件箱,而不是使用 Transport.sendMessage到re-send它。
我有 2 个电子邮件地址,我想将我的所有邮件从一个电子邮件地址路由(自动转发)到另一个电子邮件地址。不幸的是,我的邮件客户端上的这个功能停止工作了,我想创建一个小型控制台应用程序来检查我的电子邮件并每 10 分钟自动转发一次。
我开始在 Java 中使用 Java 邮件 API 开发控制台应用程序,但我在设置适当的 FROM header 时遇到问题。当我设置原始发件人电子邮件地址并尝试发送电子邮件时,SMTP 抛出异常:SMTP mail FROM does not match authenticated user name
.
它合乎逻辑,因为这样我可以伪造电子邮件地址发件人,但我不希望电子邮件像我发送的那样出现在另一封电子邮件中。出于多种原因需要这样做:
- 更容易阅读
- 当我想回复电子邮件时,我希望能够回复我的原始发件人而不是我自己
我已经使用 PHP 在我的网站联系表单上实现了这一点,但我不知道如何在 Java 中做到这一点。
我会尽量用更简单的方式解释情况。
我发送了 2 封电子邮件:a@a.com
和 b@b.com
现在电子邮件从 c@c.com
发送到 a@a.com
我想将电子邮件从 a@a.com
转发到 b@b.com
,但是当邮件到达 FROM header 中的 b@b.com
时,我想看到它来了来自 c@c.com
(不是来自 a@a.com
)
我的问题是:这是否可能,如果可能,我如何将 header FROM 设置为原始发件人。
这是我的代码:
public class ForwardMailService {
public static void forward() {
String popHost = "pop.a.com";
String popPort = "110"; // 995 SSL
String imapHost = "imap.a.com";
String imapPort = "143"; // 993 SSL
String smtpHost = "smtp.a.com";
String smtpPort = "25";
String user = "USERNAME";
String password = "PASSWORD";
Properties properties = new Properties();
properties.put("mail.store.protocol", "imap");
properties.put("mail.imap.host", imapHost);
properties.put("mail.imap.port", imapPort);
properties.put("mail.imap.starttls.enable", "true");
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.host", smtpHost);
properties.put("mail.smtp.port", smtpPort);
Session session = Session.getDefaultInstance(properties);
try {
Store store = session.getStore("imap");
store.connect(imapHost, user, password);
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_ONLY);
SearchTerm searchTerm = new SentDateTerm(ComparisonTerm.GE, new Date());
Message[] messages = folder.search(searchTerm);
if(messages.length != 0) {
for(Message message : messages) {
String from = InternetAddress.toString(message.getFrom());
String replyTo = InternetAddress.toString(message.getReplyTo());
String to = InternetAddress.toString(message.getRecipients(Message.RecipientType.TO));
String subject = message.getSubject();
Date sentDate = message.getSentDate();
Message forward = new MimeMessage(session);
forward.setRecipients(Message.RecipientType.TO, InternetAddress.parse("a@a.com));
forward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.setReplyTo(InternetAddress.parse(replyTo));
MimeBodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
messageBodyPart.setContent(message, "message/rfc822");
multipart.addBodyPart(messageBodyPart);
forward.setContent(multipart);
forward.saveChanges();
Transport transport = session.getTransport("smtp");
try {
transport.connect(smtpHost, user, password);
transport.sendMessage(forward, forward.getRecipients(Message.RecipientType.TO));
} catch(Exception ex) {
ex.printStackTrace();
} finally {
transport.close();
}
}
}
folder.close(false);
store.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
提前致谢。
这完全取决于您的邮件服务器是否允许您向 b@b.com 发送邮件而不显示它来自 a@a.com。大多数服务器不允许这样做。
一个更简单的解决方案是从 a@a.com 的收件箱中读取邮件并使用 Folder.appendMessages 将其附加到 b@b.com 的收件箱,而不是使用 Transport.sendMessage到re-send它。