We help IT Professionals succeed at work.

Please answer as quickly as possible----problems sending mail from applet, through servlet to account <br>with javamail API

markko
markko asked
on
Any help would be greatly appreciated...

I am having problems sending mail from an applet through my servlet and on to the account.
The problem seems to be that the servlet is not being activated by the applet.
I can activate it myself without the applet, with no problems.
I am using Orion web-server and JAMES mail server.
Both are running locally off a Hard Disk.

I had no problems sending the mail from an applicattion, but now that i've moved over to the applet/servlet combination I am stumped.
Note that the mail is only constructed on the servlet side, the applet merely sends the details of the mail to the servlet. The servlet constructs the message based on these details and sends it on.

The following is all of my code.
(I know there's quite a bit but don't know how much you'll need).


APPLET:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.net.URLConnection;
import java.io.*;


public class SendMailApplet extends Applet implements ActionListener
{
      
      boolean isStandalone = false;
      
      //Components to appear on-screen
      Button bLogin = new Button("Login");
            
      Label lblUserName = new Label("User Name:");
      TextField txtUserName = new TextField();
      Label lblDomainName = new Label("@mydomain.com");
      
      Label lblPassword = new Label("Password:");
      TextField txtPassword = new TextField();      
      
      Button bSend = new Button("Send");
      TextArea txtaMessage = new TextArea("",200,150,TextArea.SCROLLBARS_BOTH);
                        
      Label lblFrom = new Label("From:");
      TextField txtFrom = new TextField();
      
      Label lblTo = new Label("To:");
      TextField txtTo = new TextField();
      
      Label lblSubject = new Label("Subject:");
      TextField txtSubject = new TextField();
             
      
      /**Initialize the applet*/
      public void init()
      {
            try
            {
                  jbInit();
            }
            catch(Exception e)
            {            
              e.printStackTrace();
            }
      }
      
      
       /**Component initialization*/
      private void jbInit()
      {
            
            bSend.setLabel("Send");
            bSend.setBounds(new Rectangle(25, 48, 327, 27));
            bSend.addActionListener(this);
            
            //disable appropriate controls before verification received
            bSend.setEnabled(false);
            txtTo.setEnabled(false);
            txtFrom.setEnabled(false);
            txtSubject.setEnabled(false);            
            txtaMessage.setEnabled(false);
            //txtaMessage.setBounds(new Rectangle(25, 101, 327, 307));
                        
            bLogin.addActionListener(this);            
            
            this.setSize(new Dimension(400, 437));
            this.setLayout(new GridLayout(5,3));
            
            addComponents();
                              
      }
            
                  
            
      //add all the components to the applet
      void addComponents()
      {
            this.add(lblUserName);
            this.add(txtUserName);
            this.add(lblDomainName);
            this.add(lblPassword);
            this.add(txtPassword);
            this.add(bLogin);
            this.add(lblFrom);
            this.add(txtFrom);
            this.add(lblTo);
            this.add(txtTo);      
            this.add(lblSubject);
            this.add(txtSubject);
          this.add(txtaMessage);
            this.add(bSend);
      }
      
      /**Get a parameter value*/      
      public String getParameter(String key, String def)
      {
            return isStandalone ? System.getProperty(key, def) :
                                            (getParameter(key) != null ? getParameter(key) : def);
      }
      
      /**Get Applet information*/
      public String getAppletInfo()
      {
          return "Applet Information";
      }
      
      
      /**Get parameter info*/
      public String[][] getParameterInfo()
      {
            return null;
      }
      
      public void actionPerformed(ActionEvent e)
      {
            if(e.getSource() == bSend)
            {
                  
                  try
                  {
                                    
                        URL curPage = getCodeBase();
                        String prot = curPage.getProtocol();
                        String host = curPage.getHost();
                        int port = curPage.getPort();
                        String urlsfx = "/servlet/SendMailServlet";
        
                        URL dataURL = new URL(prot,host,port,urlsfx);
                        URLConnection con = dataURL.openConnection();
                        con.setUseCaches(false);//instruct browser not to cache results
                        con.setDoOutput(true);//allow the applet to send data
            
                        
                        //512 is the initial size of the strewam but this will grow automatically if needed
                        ByteArrayOutputStream bs = new ByteArrayOutputStream(512);
                        ObjectOutputStream out = new ObjectOutputStream(bs);
            
                        //Create the message details to be sent to the servlet
                        MessageDetails messageDetails = new MessageDetails(txtUserName.getText(),
                               txtPassword.getText(), txtTo.getText(),
                               (txtFrom.getText()+ lblDomainName.getText()),
                                txtSubject.getText(),txtaMessage.getText());
            
                        out.writeObject(messageDetails);
                        out.flush();
                        
                        con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
                        con.setRequestProperty("Content-Length",String.valueOf(bs.size()));
                        bs.writeTo(con.getOutputStream());
                                                
                        
                        //txtaMessage.setText("Mail sent successfully");
                        
                  }
                  catch(IOException eee)
                  {
                        eee.printStackTrace();
                        txtaMessage.setText("Error: " + eee);
                                                   
                  }
            }
            
            if(e.getSource() == bLogin)
            {
                  bSend.setEnabled(true);
                  txtTo.setEnabled(true);
                  txtFrom.setText(txtUserName.getText() + lblDomainName.getText());
                  txtSubject.setEnabled(true);            
                  txtaMessage.setEnabled(true);
            }
                                            
      }
      
}



//This is the message details to be sent to the servlet.
class MessageDetails implements java.io.Serializable
{
      String user,password;
      String to,from;
      String subject,mailBody;
      
      MessageDetails(String u, String pwd, String t,String fr, String subj, String mBody)
      {
            
            user = u;
            password= pwd;
            to = t;
            from = fr;
            subject = subj;
            mailBody = mBody;
            
      }      
            
}




SERVLET:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.Transport;

import javax.activation.*;


public class SendMailServlet extends HttpServlet
{
      
      private static final String CONTENT_TYPE = "text/html";
      
      /**Initialize global variables*/
      
      public void init(ServletConfig config) throws ServletException
      {
            //always call super.init()
            super.init(config);
            System.out.println("Servlet init");
      }
      
      public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
      {
            doPost(request,response);
      }
      
      /**Process the HTTP Post request*/
      public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
      {
            System.out.println("Servlet started");
            HttpSession hs = request.getSession(true);            
            
            try
            {
                  //read in the message details from the applet
                  //i.e. to, from, subject etc.
                  ObjectInputStream in = new ObjectInputStream(request.getInputStream());
                  MessageDetails msgdet = (MessageDetails)in.readObject();
                  
                  in.close();
                              
                  //send the mail
                  sendMail(msgdet);
            }
            catch(IOException ioe)
            {}
            catch(ClassNotFoundException cnfe)
            {}
            catch(MessagingException me)
            {}            
            /*catch(ServletException se)
            {}*/
            
      }
      
      
      void sendMail(MessageDetails mailDetails) throws MessagingException
      {
            
            try
            {
      
                  boolean debug = false;
            
                  //Set the host smtp address
                  Properties props = new Properties();
                  props.put("mail.smtp.host", "smtp.localhost");

                  // create some properties and get the default Session
                  Session session = Session.getDefaultInstance(props, null);
                  session.setDebug(debug);
                  System.out.println("session done");
                  // create a message
                  Message msg = new MimeMessage(session);

                  // set the from address
                  System.out.println("From: "+mailDetails.from);
                  InternetAddress addressFrom = new InternetAddress(mailDetails.from);
                  msg.setFrom(addressFrom);
            
                  //set the to address(es)                  
                  int noOfAddresses = getNoOfAddresses(mailDetails.to);
                  System.out.println("noOFAddresses "+noOfAddresses);
                  if(noOfAddresses != 0)
                  {
                        String recip[] = parse(mailDetails.to,noOfAddresses);
                        InternetAddress[] addressTo = new InternetAddress[noOfAddresses];
                        for (int i = 0; i < recip.length; i++)
                        {
                              addressTo[i] = new InternetAddress(recip[i]);
                        }
                        msg.setRecipients(Message.RecipientType.TO, addressTo);
                  }
        

                  // Optional : You can also set your custom headers in the Email if you Want
                  //msg.addHeader("MyHeaderName", "myHeaderValue");

                  // Setting the Subject and Content Type
                  msg.setSubject(mailDetails.subject);
                  msg.setContent(mailDetails.mailBody, "text/plain");
            
                  Transport transport = session.getTransport("smtp");
                  transport.connect("localhost", mailDetails.user + "@mydomain.com", mailDetails.password);
                  transport.sendMessage(msg, msg.getAllRecipients());
                  transport.close();
            }
            catch(MessagingException me)
            {
                  me.printStackTrace();
            }
      }
      
      
      public static int getNoOfAddresses(String to)
      {
            int noOfAddresses = 0;
            
            //find out how many addresses are contained in the text
            for( int i=0;i<to.length();i++)
            {
                  if(to.charAt(i) == '@')
                  {
                        noOfAddresses++;
                  }
            }
            return noOfAddresses;
      }
      
      
      public static String[] parse(String to, int noOfAddresses)
      {
            
                        
            //This method will return an array of the properly formatted addresses
            // minus spaces and commas
            String[] returnString = new String[noOfAddresses];
                  
            char temp[] = new char[to.length()];
                        
            int count =0;
                        
            for(int j = 0;j < to.length();j++)
            {
                  
                  if( (to.charAt(j) != ',') && (to.charAt(j) != ' ') )
                  {
                        temp[j] = to.charAt(j);                  
                  }      
                  else
                  {
                        //save as one address in String array
                        returnString[count] = new String(temp);      
                        returnString[count] = returnString[count].trim();
                        if( returnString[count].length()!= 0 )
                        {
                              count++;
                        }
                        
                        //fill character array with spaces.
                        for(int s=0;s<temp.length;s++)
                        {
                              temp[s] = ' ';
                        }
                                                
                  }
                                    
            }
            //Needs to be outside due to array indexing complexities
            //Only way it will work
            returnString[count] = new String(temp);      
            returnString[count] = returnString[count].trim();
            
            return returnString;
            
      }            
      
}

class MessageDetails implements java.io.Serializable
{
      String user,password;
      String to,from;
      String subject,mailBody;
      
      MessageDetails(String u, String pwd, String t,String fr, String subj, String mBody)
      {
            
            user = u;
            password= pwd;
            to = t;
            from = fr;
            subject = subj;
            mailBody = mBody;
                        
      }      
            
}





Comment
Watch Question

I think you have to tell the URLConnection to POST the request. Use URLConnection.setRequestMethod( "POST");

You probably also should use URLConnection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");

Next, you will have to URLEncode your parameters like this:

user=u&password=pwd&to=t... [you get the idea]

You will have to make sure that the values of the parameters are URL-encoded. Use java.net.URLEncoder.encode( String) to do that.

Then, in the servlet, you won't have to parse any incoming object. You can pick up the values of each parameter with the generic req.getParameter( "user"), for instance.



The alternative method you are trying (to serialize the MessageDetails object in the applet, then use ObjectInputStream.readObject() in the servlet, probably won't be so simple to implement. For one, you should wrap the binary object in a proper HTTP envelope, which is signified by
     
URLConnection.setRequestProperty( "Content-Type", "multipart/form-data");

Then, you would have to put your binary object stream inside a MIME part. Once you have done that, you are following the same protocol as is used when you upload a file to a web server.

1. See if the URL is correct by printing out what dataURL has
2. May be the whole object isnt fitting in to the ByteArrayOutput stream.  Try increasing the size of the ByteArrayOutputStream to something more, say, 2048 and see if it works.
3. I suggest you test your applet with AppletViewer first and then with your browser as its faster to debug with applet viewer than with the browser.  Also, since the browser may cache the applet class file, your code changes may not get reflected in the browser.
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:

- To be PAQ'ed and points refunded

Please leave any comments here within the
next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !

girionis
Cleanup Volunteer
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
 Sorry I meant points *NOT* refunded. Sorry for my mistake.
PAQ'ed and points NOT refunded

DigitalXtreme
CS Moderator

Explore More ContentExplore courses, solutions, and other research materials related to this topic.