Question

In my small project, I want to setup the "RCPT TO" and "To" look like this:

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

And I tried with the following code

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());
}

And the log I got

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>

As you see, the program created a new "RCPT TO" value with "+10xxxxxxxxxx".

How can I set "RCPT TO" value that will not match with "To" header in DATA?

Was it helpful?

Solution

I just had a look at the source code of MimeMessageHelper you will see that the setTo() functions all call javax.mail.Message#setRecipient just like you did the command before using the Helper.

I see two solutions using JavaMail:

Extend MimeMessage and override getAllRecipients() as this method is used to determine recipients in 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());
    }
}

Write your own send method and use Transport#sendMessage(javax.mail.Message, javax.mail.Address[]) directly

Based upon the spring-wrapper around 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);
        }
    }
}

OTHER TIPS

The trick to sending mail to a "RCPT To" address and including other "To" addresses in the mail without actually sending the mail to other "To" is to use message.send(message, InternetAddress) instead of message.send(message) and set the other "To" in message.setRecipients

Here's the code snippet:

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);**
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top