narasimhulu madhana
narasimhulu madhana

Reputation: 107

how to configure two different emails in springboot?

I know I can use the following properties to automatically create a JavaMailSender bean:

spring.mail.host=hostname
spring.mail.port=587
spring.mail.username=username
spring.mail.password=password

However, how can I define these properties to create two JavaMailSender beans so I can send emails from different SMTP servers?

I tried defining the following properties:

# Properties for sender 1
spring.mail.host=hostname
spring.mail.port=587
spring.mail.username=username
spring.mail.password=password

# Properties for sender 2
spring.mail.host1=hostname2
spring.mail.port1=587
spring.mail.username1=username2
spring.mail.password1=password2

However, this does not work as I expected, so how can I create two JavaMailSender beans using Spring boot?

Upvotes: 6

Views: 8373

Answers (3)

redfelix
redfelix

Reputation: 1

Configure Two different SMTP emails in springboot

The correct configuration is:

For a correct injection of the javaMailProperties it is necessary to read the keys manually by means of the relative prefix.

Bean


@Configuration
public class EmailConfig {
    public static final String MAIL_SENDER_PRIMARY_KEY = "spring.mail.primary";
    public static final String MAIL_SENDER_PRIMARY_PROPERTIES_KEY = "spring.mail.primary.properties";
    public static final String MAIL_SENDER_SECONDARY_KEY = "spring.mail.secondary";
    public static final String MAIL_SENDER_SECONDARY_PROPERTIES_KEY = "spring.mail.secondary.properties";
    
    public static final String KEY_SEPARATOR = ".";
    public static final String EMPTY_STRING = "";

    @Autowired
    Environment env;

    @Bean
    @ConfigurationProperties(prefix = MAIL_SENDER_PRIMARY_KEY)
    public JavaMailSender primarySender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        return javaMailSenderWithProperties(javaMailSender,MAIL_SENDER_PRIMARY_PROPERTIES_KEY);
    }

    @Bean
    @ConfigurationProperties(prefix = MAIL_SENDER_SECONDARY_KEY)
    public JavaMailSender secondarySender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        return javaMailSenderWithProperties(javaMailSender,MAIL_SENDER_SECONDARY_PROPERTIES_KEY);
    }

    private JavaMailSender javaMailSenderWithProperties(JavaMailSenderImpl javaMailSender, String prefix) {
        Properties props = new Properties();
        if (env instanceof ConfigurableEnvironment) {
            for (PropertySource<?> propertySource : ((ConfigurableEnvironment) env).getPropertySources()) {
                if (propertySource instanceof EnumerablePropertySource) {
                    for (String key : ((EnumerablePropertySource) propertySource).getPropertyNames()) {
                        if (key.startsWith(prefix)) {
                            props.setProperty(key.replaceAll(prefix + KEY_SEPARATOR, EMPTY_STRING), propertySource.getProperty(key).toString());
                        }
                    }
                }
            }
        }

        javaMailSender.setJavaMailProperties(props);
        return javaMailSender;
    }
}

Configuration

Properties of PrimarySender

spring.mail.primary.username=
spring.mail.primary.password=
spring.mail.primary.host=
spring.mail.primary.port=
spring.mail.primary.protocol=smtp
spring.mail.primary.properties.mail.smtp.auth=true
spring.mail.primary.properties.mail.smtp.connectiontimeout=5000
spring.mail.primary.properties.mail.smtp.timeout=5000
spring.mail.primary.properties.mail.smtp.writetimeout=5000
spring.mail.primary.properties.mail.smtp.socketFactory.class=
spring.mail.primary.properties.mail.smtp.socketFactory.port=
#spring.mail.primary.properties.mail.smtp.auth=true
spring.mail.primary.properties.mail.smtp.starttls.enable=true
spring.mail.primary.properties.mail.smtp.starttls.required=true

Properties of SecondarySender

spring.mail.secondary.host=
spring.mail.secondary.port=
spring.mail.secondary.username=
spring.mail.secondary.password=
spring.mail.secondary.protocol=
spring.mail.secondary.properties.mail.smtp.auth=true
spring.mail.secondary.properties.mail.smtp.connectiontimeout=5000
spring.mail.secondary.properties.mail.smtp.timeout=5000
spring.mail.secondary.properties.mail.smtp.writetimeout=5000
spring.mail.secondary.properties.mail.smtp.socketFactory.class=
spring.mail.secondary.properties.mail.smtp.socketFactory.port=
#spring.mail.secondary.properties.mail.smtp.auth=true
spring.mail.secondary.properties.mail.smtp.starttls.enable=true
spring.mail.secondary.properties.mail.smtp.starttls.required=true

Usage


@Service
public class EmailService {

    private JavaMailSender primarySender;
    private JavaMailSender secondarySender;

    public EmailService (
        @Qualifier("primarySender") JavaMailSender primarySender,
        @Qualifier("secondarySender") JavaMailSender secondarySender) {
        this.primarySender = primarySender;
        this.secondarySender = secondarySender;
    }

    public void sendPrimaryEmail(String from, String to, String subject, String text){
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(text);
        
        primarySender.send(message);

    }

 public void sendSecondaryEmail(String from, String to, String subject, String text) 
       {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(text);
        
        secondarySender.send(message);

    }
}

Upvotes: 0

Dany Alfaro
Dany Alfaro

Reputation: 41

If you are using the mail properties, at least in my case, the mail properties were not read with the @ConfigurationProperties. So I change the solution a bit:

@Bean
@ConfigurationProperties(prefix = "spring.mail.primarySender")
public JavaMailSender primarySender() {
    JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
    return javaMailSenderWithProperties(javaMailSender);
}

@Bean
@ConfigurationProperties(prefix = "spring.mail.secondarySender")
public JavaMailSender secondarySender() {
    JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
    return javaMailSenderWithProperties(javaMailSender);
}

private JavaMailSender javaMailSenderWithProperties(JavaMailSenderImpl javaMailSender) {
    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    javaMailSender.setJavaMailProperties(props);
    return javaMailSender;
}

Upvotes: 4

Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44725

Creating the beans

Spring boot will only initialize one JavaMailSender as soon as it finds the spring.mail.* properties. If you need multiple ones, you have to define these beans by yourself. If you only need the properties host, port, username and password, you could use this simple configuration:

@Configuration
public class MailConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.mail.primary")
    public JavaMailSender primarySender() {
        return new JavaMailSenderImpl();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.mail.secondary")
    public JavaMailSender secondarySender() {
        return new JavaMailSenderImpl();
    }
}

However, this will not work if you also want to configure spring.mail.properties.* as well. In order to do that, your configuration will be a bit more complex, since you'll have to do the following:

  • Create two beans of MailProperties using the same @ConfigurationProperties as you can see above.
  • Use the MailProperties in a similar way as Spring boot does within MailSenderPropertiesConfiguration.

Configuration

After that, you can use the spring.mail.primary.* properties and spring.mail.secondary.* properties as you're used to. For example:

spring.mail.primary.host=host1
spring.mail.primary.port=port1
spring.mail.primary.username=username1
spring.mail.primary.password=password1
spring.mail.secondary.host=host2
spring.mail.secondary.port=port2
spring.mail.secondary.username=username2
spring.mail.secondary.password=password2

Usage

After that, you can autowire both primarySender and secondarySender. Make sure to use the @Qualifier annotation to tell Spring which is which:

@Service
public class MailService {
    private JavaMailSender primarySender;
    private JavaMailSender secondarySender;

    public MailService(
        @Qualifier("primarySender") JavaMailSender primarySender,
        @Qualifier("secondarySender") JavaMailSender secondarySender) {
        this.primarySender = primarySender;
        this.secondarySender = secondarySender;
    }
}

Upvotes: 21

Related Questions