Discussions

Web tier: servlets, JSP, Web frameworks: How to send emails from servlets using threads

  1. How to send emails from servlets using threads (5 messages)

    Hi guys. I have a class (MyMailer) with static methods to send email.

    MyMailer.send(to,from,subject,message, etc..)

    so in my servlet I just invoke this class and it is working ok. But what I really want is to create a separate thread to send many emails but I'm not quite sure how is the procedure for this. Do you start the thread in the servlet?, or do you start the thread in the class?? sorry for this basic question.

    cheers

  2. I would hide the thread behind the send(to, from, subject, message, etc.) method.

    This would abstract the implementation of sending from the servlet layer.

    e.g. something like this:

    MyServlet:
    public void doGet(...)
    {
      // figure out what to do, who to send to, etc.
      MyMailer.send(...);
      // forward to a JSP or whatever
    }

    MyMailer:
    public class MyMailer implements Runnable
    {
      // prevent creating threads from outside this class'
      // public methods...
      private MyMailer()
      {
      }

      // provide service to external code
      public static void send(...)
      {
        MyMailer mm = new MyMailer();
        mm.setToAddress(...);
        mm.setFromAddress(...);
        (new Thread(mm)).start();
        return;
      }

      // perform the actual work in a separate thread
      // (this method is called due to Thread.start()
      // being called from the send() method).
      public void run()
      {
        // send email using JavaMail API
      }
    }
  3. i would post it to a queue (perhaps using JMS), and let the subscriber handle the emailing.

    alex
  4. Guys, I'm having a problem. It's not sending mails anymore, is this the way to do it?

    public class MyMailer implements Runnable
    {
        private static String[] to_ = new String[] {};
        private static String from_;
        private static String smtp_;
        private static String subject_;
        private static String message_;
       
        private MyMailer() {}

        protected static Message prepareHeader(String smtp_host, String from,String to, String subject) throws IOException, AddressException, MessagingException
        {
            Properties props = new Properties();
            props.put("smtp.host", smtp_host);
            Session session = Session.getDefaultInstance(props, null);
            Message msg = new MimeMessage(session);
            InternetAddress addr = new InternetAddress(to);
            msg.addRecipients(Message.RecipientType.TO,new InternetAddress[] {addr });
            InternetAddress from_addr = new InternetAddress(from);
            msg.setFrom(from_addr);
            msg.setSubject(subject);
            return msg;
        }

        public static void sendMail(String smtp_host, String from,String [] to, String subject, String message) throws IOException, AddressException,MessagingException
        {
            from_ = from;
            to_ = to;
            smtp_ = smtp_host;
            subject_ = subject;
            message_ = message;
            MyMailer mm = new MyMailer();

            // support to start a thread
            (new Thread(mm)).start();
            return;
       }


        public void run()
        {
           for (int i = 0; i < to_.length; i++)
           {
              try
              {
    Message msg = prepareHeader(smtp_, from_, to_[i], subject_);
                 msg.setContent(message_, "text/plain");
                 Transport.send(msg);
              }
              catch (Exception e)
              {}
           }
        }

    in my servlet I only do
    MyMailer.sendMail(parameters)...

    any ideas ??? :-(
  5. any suggestions...?? :-S
  6. One way to implement a threaded emailing servlet is to create a database table corresponding to your emails (to, from, etc...). Using the DAO pattern, you can add emails to the table as you wish, even from outside the servlet container should you so wish. A preloaded threaded servlet can then periodically wake up, gather all the outgoing mail, mail it, and go back to sleep.

    Enhancing this model, you can place a desired mail date stamp on each row, allowing you to create email ahead of time and have it sit in the database until its mail date arrives.

    The servlet might look similar to the following:

    public class SimpleMailServer extends HttpServlet implements Runnable
    {
       Thread mailServer;
       int mailServerInterval = 5000;

       public void init( ServletConfig config ) throws ServletException
       {
          super.init( config );
          this.mailServer = new Thread( this );
          this.mailServer.setPriority( Thread.MIN_PRIORITY );
          this.mailServer.start();
       }

       public void run()
       {
          while ( this.mailServer != null )
          {
             // Your Mail Processing Here
             this.mailServer.sleep( mailServerInterval );
          }
       }

       public void destroy()
       {
          // Cleanup Code Here
          this.mailServer = null;
       }
    }

    Hope that helps.
    eric