Proper design of a class, that connects to an SMTP server, authenticates and sends a message (using JavaMail API)

StackOverflow https://stackoverflow.com/questions/7638856

  •  06-02-2021
  •  | 
  •  

Question

This is kind of a beginner question. For now I have the implementation like this:

package org.minuteware.jgun;

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

class EmailNotifier {
    static Session connect(String host) {
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.from", "from@ex.com");
        Session session = Session.getInstance(props, null);

        return session;
    }

    static void send(String to, String subject, String body) {
        try {
        MimeMessage msg = new MimeMessage(connect("mail.ex.com"));
            msg.setRecipients(Message.RecipientType.TO, to);
            msg.setSubject(subject);
            msg.setSentDate(new Date());
            msg.setText(body);
            Transport.send(msg);
        } catch (MessagingException mex) {
            System.out.println("send failed, exception: " + mex);
        }
    }
    public static void main(String[] args) {
        send("to@ex.com", "test subj", "test body");
    }
}

What I'm stuck with is passing the host parameter to the send() method so that it could create a session. Another option could be to have only one method and pass all the parameters to it. But that's quite ugly. In Python I could create the connection in the class constructor, and then use this connection with prefix self throughout all the other methods of the class. But I cannot find a way to do this is Java.

Was it helpful?

Solution

Your mistake is that you did not make it the object-oriented way because you created static methods. Let's say the caller of your class should look like this:

public static void main(String[] args) {
    EmailNotifier en = new EmailNotifier("my.smtpserver", "sender@smtpserver");
    en.send("to@ex.com", "test subj", "test body");
    en.send("to@ex.com", "test subj", "test body");
    en.send("to@ex.com", "test subj", "test body");
}

Then your notifier may look similar to this:

class EmailNotifier {
    private final Session session;

    public EmailNotifier(final String host, final String sender) {
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.from", sender);
        this.session = Session.getInstance(props, null);
    }

    public void send(String to, String subject, String body) {
        try {
            MimeMessage msg = new MimeMessage(this.session);
            msg.setRecipients(Message.RecipientType.TO, to);
            msg.setSubject(subject);
            msg.setSentDate(new Date());
            msg.setText(body);
            Transport.send(msg);
        } catch (MessagingException mex) {
            System.out.println("send failed, exception: " + mex);
        }
    }
}

Edit: Apache commons provides a nice wrapper around javax.mail which you can find here.

OTHER TIPS

You can obtain the Session object configured with the host from a Configuration class internally in the send(String, String, String) method.

The host through which the messages are sent is a configuration setting which should be externalized to a property file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top