在我的小项目中,我想设置"RCPT TO"和"To"看起来像这样:
RCPT TO: <user-signup-123123123@bounces.example.com>
DATA
354 Go ahead vw9sm7458976pbc.68 - gsmtp
Date: Thu, 02 Mar 2012 14:06:02 +0200 (ICT)
To: +10xxxxxxxxxx
我尝试使用以下代码
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("HOST");
mailSender.setPort("PORT");
mailSender.setUsername("USERNAME");
mailSender.setPassword("PASSWORD");
MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
mimeMessage.setRecipient(MimeMessage.RecipientType.TO,
new InternetAddress("user-signup-123123123@bounces.example.com"));
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setTo("+10xxxxxxxxxx");
} catch(Exception e) {
System.out.println(e.getMessage());
}
还有我得到的日志
MAIL FROM:<abc@xxxxx.com>
250 2.1.0 OK x5sm16625925pbw.26 - gsmtp
RCPT TO:<user-signup-123123123@bounces.example.com>
250 2.1.5 OK x5sm16625925pbw.26 - gsmtp
RCPT TO:<+10xxxxxxxxxx>
如您所见,该程序创建了一个新的"RCPT TO"值,其中包含"+10xxx
"。如何设置与 DATA 中的"收件人"标头不匹配的"RCPT TO"值?
我刚刚看了一下源代码MimeMessageHelper
你会发现setTo()
函数都调用javax.mail.Message#setRecipient,就像你在使用帮助程序之前执行命令一样。
我看到两种使用JavaMail的解决方案:
扩展MimeMessage
并覆盖getAllRecipients()
,因为此方法用于确定JavaMailImpl
中的收件人
// yes you need to use this package as SmartMimeMessage is package-private or you loose spring advantages
package org.springframework.mail.javamail;
import javax.activation.FileTypeMap;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
/**
* Created for http://stackoverflow.com/q/22860793/1266906
*/
public class RoutedSmartMimeMessage extends SmartMimeMessage {
private Address[] rcptTo = null;
/**
* Create a new SmartMimeMessage.
*
* @param session
* the JavaMail Session to create the message for
* @param defaultEncoding
* the default encoding, or {@code null} if none
* @param defaultFileTypeMap
* the default FileTypeMap, or {@code null} if none
*/
public RoutedSmartMimeMessage(final Session session,
final String defaultEncoding,
final FileTypeMap defaultFileTypeMap) {
super(session, defaultEncoding, defaultFileTypeMap);
}
public Address[] getRcptTo() {
return rcptTo;
}
public void setRcptTo(final Address... rcptTo) {
this.rcptTo = rcptTo;
}
@Override
public Address[] getAllRecipients() throws MessagingException {
if(rcptTo != null) {
return rcptTo;
} else {
return super.getAllRecipients();
}
}
public static MimeMessage createMesage(final JavaMailSenderImpl javaMailSender) {
return new SmartMimeMessage(javaMailSender.getSession(), javaMailSender.getDefaultEncoding(), javaMailSender.getDefaultFileTypeMap());
}
}
编写自己的发送方法并直接使用 Transport#sendMessage(javax.mail.Message, javax.mail.Address[])
基于 JavaMail 的弹簧包装器:
import org.springframework.mail.MailAuthenticationException;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created for http://stackoverflow.com/q/22860793/1266906
*/
public class Mailing {
public static void main(String[] args) {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("HOST");
mailSender.setPort(25);
mailSender.setUsername("USERNAME");
mailSender.setPassword("PASSWORD");
MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
/*
Not needed
mimeMessage.setRecipient(MimeMessage.RecipientType.TO,
new InternetAddress("user-signup-123123123@bounces.example.com"));
*/
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setTo("+10xxxxxxxxxx");
sendMail(mailSender, mimeMessage, new InternetAddress("user-signup-123123123@bounces.example.com"));
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
/**
* Adopted from {@link org.springframework.mail.javamail.JavaMailSenderImpl#doSend(javax.mail.internet.MimeMessage[], Object[])} to be able to call {@link javax.mail.Transport#send(javax.mail.Message, javax.mail.Address[])} with a different second parameter than {@link javax.mail.Message#getAllRecipients() mimeMessage.getAllRecipients()}
*
* @param javaMailSender
* JavaMailSender object holding configuration options
* @param mimeMessage
* MimeMessage object to send
* @param realRecipients
* RCPT TO: sddresses
* @throws org.springframework.mail.MailAuthenticationException
* in case of authentication failure
* @throws org.springframework.mail.MailSendException
* in case of failure when sending a message
*/
private static void sendMail(final JavaMailSenderImpl javaMailSender,
final MimeMessage mimeMessage,
final Address... realRecipients) throws MailException {
final Map<Object, Exception> failedMessages = new LinkedHashMap<Object, Exception>();
final Transport transport;
try {
Session session = javaMailSender.getSession();
String protocol = javaMailSender.getProtocol();
if (protocol == null) {
protocol = session.getProperty("mail.transport.protocol");
if (protocol == null) {
protocol = JavaMailSenderImpl.DEFAULT_PROTOCOL;
}
}
transport = session.getTransport(protocol);
transport.connect(javaMailSender.getHost(),
javaMailSender.getPort(),
javaMailSender.getUsername(),
javaMailSender.getPassword());
} catch (AuthenticationFailedException ex) {
throw new MailAuthenticationException(ex);
} catch (MessagingException ex) {
failedMessages.put(mimeMessage, ex);
throw new MailSendException("Mail server connection failed", ex, failedMessages);
}
try {
try {
if (mimeMessage.getSentDate() == null) {
mimeMessage.setSentDate(new Date());
}
String messageId = mimeMessage.getMessageID();
mimeMessage.saveChanges();
if (messageId != null) {
// Preserve explicitly specified message id...
mimeMessage.setHeader("Message-ID", messageId);
}
transport.sendMessage(mimeMessage, realRecipients);
} catch (MessagingException ex) {
failedMessages.put(mimeMessage, ex);
}
} finally {
try {
transport.close();
} catch (MessagingException ex) {
if (!failedMessages.isEmpty()) {
throw new MailSendException("Failed to close server connection after message failures", ex,
failedMessages);
} else {
throw new MailSendException("Failed to close server connection after message sending", ex);
}
}
}
if (!failedMessages.isEmpty()) {
throw new MailSendException(failedMessages);
}
}
}
将邮件发送到"RCPT 收件人"地址并在邮件中包含其他"收件人"地址而不实际将邮件发送到其他"收件人"的技巧是使用message.send(message, InternetAddress) 而不是 message.send(message)并在 message.setRecipients 中设置其他"收件人"
下面是代码片段:
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress[] addresses = new InternetAddress[recipientaddresstoshowinmail];
message.setRecipients(Message.RecipientType.TO, addresses);
message.setSubject(subject);
message.setText(body);
InternetAddress[] toaddress = new InternetAddress[] {new InternetAddress(to)};
**Transport.send(message, actualtoaddress);**