Sunday, May 25, 2014

How To: Make an E-Mail sending Website that uses your GMail account to send EMails [JSP] [Apache/Tomcat Web Server] [Note]

So we're gonna make a website which will make use of the GMail account information of the user to send E-Mails. The final web site is gonna look like this:

Start page:

Compose Page:
If the delivery succeeds:
else:

You should have a good understanding of general Java code. We're gonna learn about JSP and Tomcat basics using this example.

1. What is JSP actually?

JavaServer Pages (JSP) is a technology that helps software developers create dynamically generated web pages based on HTML,XML, or other document types.

In short, HTML+JAVA = JSP

2. What is Apache/Tomcat?

Apache Tomcat  is an open source web server and servlet container developed by the Apache Software Foundation (ASF). Tomcat implements the Java Servlet and the JavaServer Pages (JSP) specifications fromSun Microsystems, and provides a "pure JavaHTTP web server environment for Java code to run in.

Tomcat is used to process client requests for web pages. It can run on any system. On a local network, a single server running Tomcat can serve other client requests on the network. Same applies when running on a server connected to internet.

Download Apache Tomcat from here.
Download NetBeans [with Java EE support] from here. (Makes work a lot easier)

Setup Tomcat properly -

1. Set system environment variable "JAVA_HOME" to "C:\Program Files\Java\jdk1.7.0_45\" or wherever JDK is installed on your system. Make sure not to include \bin.
2. Set system environment variable "JRE_HOME" to "C:\Program Files\Java\jre7\" or wherever JRE is installed on your system. Again, make sure not to include \bin.

Set Tomcat as the server in NetBeans when making a new "Java Web -> Web Application" project.

We will require 5 pages:

1. index.jsp
2. working.jsp (or whatever name you want to give)
3. Home.jsp
4. send.jsp
5. errorpage.jsp

1. Pages are always put in WEB-INF folder
2. Compiled class files are always put in WEB-INF\classes\  "rest directory structure according to the package name"  [Make sure to restart tomcat after recompiling the .java file and reinserting it back when you're not using NetBeans]

The code for index.jsp :

<%@page contentType="text/html" pageEncoding="UTF-8"  errorPage="errorpage.jsp"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Quick Mail</title>
    </head>
    <body>
    <center>
        <h2>Welcome to Quick Mail.</br>
            <h2>Use Quick Mail to send EMails using your GMail account</h2>
            <FORM action="working.jsp" method="post">
                Username:
                <INPUT type="text" name="username" size="20">
                <BR>
                Password:
                <INPUT type="password" name="password" size="20">
                <BR>
                <INPUT type="submit" value="Login">
            </FORM>
        </h2>
    </body>
</html>


page: page is used to provide the information about it.
Example: <%@page language="java" %> 

content type specifies the type of content.
pageEncoding specifies the Encoding used.
errorPage specifies the path of the page to display in case something goes wrong.

You should be familiar with basic HTML. If not, quick references at here might be useful.
The FORM tag has action attribute which specifies the page to give the information received from user to.
Method attribute can have two values : POST (secure) and GET(insecure, uses URLs to pass information)
We'll be using POST as we need to transmit passwords.
Input tag displays a user input area. The TYPE tag specifies the type of input field to use. We need to get TEXT input so we've given the value TEXT. Size specifies the number of columns (the number of rows is 1 and can't be changed for TEXT type).
"submit" TYPE is used to send all the data between <FORM> and </FORM> to the page that is specified to handle this. We did specify the page as "working.jsp" in ACTION attribute of FORM tag. The VALUE attribute specifies the text to be displayed on the button which submits the input to the next page.

An intermediate page "working.jsp" is created. This page just receives the values form the user and stores them in a class object that needs to be specified. Have a look at the code: 

<%@page contentType="text/html" pageEncoding="UTF-8"  errorPage="errorpage.jsp"%>
<!DOCTYPE html>
<jsp:useBean id="user" class="quickmail.user" scope = "session" />
<jsp:setProperty name="user" property="*"/>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Working</title>
    </head>
    <body>
        <%  response.sendRedirect("Home.jsp");   %>
            
    </body>
</html>

Here we've used two new constructs: jsp:useBean and jsp:setProperty
Bean is just a class object that handles the data from Action tag.
The id attribute specifies the name of the bean. 
Scope specifies where the bean is stored.
The class attribute specifies the fully qualified class name.
So the code says that the class file must be in directory WEB-INF\classes\quickmail" folder and the name of the class file should be user.class . If any unexpected error occurs, the user is redirected to errorpage.jsp .

The setProperty tag can be used in three ways:

jsp:setProperty name="instanceOfBean" property= "*"

Name is the name of instance of the Bean to be used i.e. "user" in our case. property="*" specified that all the supplied information be put into the data elements of the bean class code.

The second way to use this tag is to specifies specific properties that should be updated:

   <jsp:setProperty name="bean" property="username" />  

You can also specify a specific value to a field using the value attribute: 

    <jsp:setProperty name="bean" property="username" value="MyName" />

Be careful about the ending / to end the tag.  

<%  response.sendRedirect("Home.jsp");   %>

This is a scriplet (Java code written in between HTML in JSP file). Note that scriplets start with <% and end with %>

Normal Java code can be inserted in between.

response is a predefined object with sendRedirect("path") method to redirect the client to the specified page.

The code for our user class is:

package quickmail;

public class user {
    String username;
    String password;
    
    public void setUsername(String user){
        this.username=user;
    }
    public void setPassword(String pass){
        password=pass;
    }
    public String getUsername(){
        return username;
    }
    public String getPassword(){
        return password;
    }
}


Three things to note:

1. Use getters and setters with the name of the setter function as setFunction. The first letter must be capital after "set".
2. Class should be public.
3. Must have a no-arg public constructor.

Now we write Home.jsp to which the client must be redirected: [note also that filenames are case sensitive so home.jsp would not work)

<%@page contentType="text/html" pageEncoding="UTF-8"  errorPage="errorpage.jsp"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Compose Mail</title>
    </head>
    <body>
    <center>
        
        <FORM action="send.jsp" method="post">
          
        <h1>Compose Mail</h1>
          
              To:
              <INPUT type="text" name="to" size="20"><br>
              Subject:
              <INPUT type="text" name="subject" size="20"><br>
              Body:
              <br>
              <textarea name="body" rows="20" cols="50"></textarea><br>
              <INPUT type="submit" value="Send">
          </FORM>
        <br><br>
        <a href="index.jsp"><h2>Login Using Another ID</h2></a>
    </body>
</html>

Nothing new here. Just new <textarea> tag to increase the number of rows for user input for the "body" of the EMail message.

This redirects the user to send.jsp :

<%@page contentType="text/html" pageEncoding="UTF-8"  errorPage="errorpage.jsp"%>
<!DOCTYPE html>
<jsp:useBean id="user" class="quickmail.user" scope = "session" />
<jsp:useBean id="message" class="quickmail.message" scope = "session" />
<jsp:setProperty name="message" property="*"/>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sending Mail</title>
    </head>
    <body>
        <% 
            try{
            new quickmail.mail(user.getUsername(), user.getPassword(), message.getTo(), message.getSubject(), message.getBody());
            out.println("Mail sent successfully");
            message.setBody("");
            message.setSubject("");
            message.setTo("");
            %>
                <a href="Home.jsp"><h1>Send Another E-Mail</h1>
            <%
            }catch(Exception e){
                out.println("Mail was not sent!");
                %>
                <a href="index.jsp"><h1>Try Again</h1>
                <%
            }    
        %>
    </body>
</html>

Note that we have to use try-catch blocks in case exceptions have a chance to occur.

The message bean stores the input from the previous page. And a new class quickmail.mail has the actual logic of sending the E-Mail message. If mail is successfully sent (no exceptions are raised, we display "Mail sent successfully" and add a link to home.jsp to allow user to send another mail (if the user wishes -.-). If an exception is raised (like you entered an email address - ihateyou@mylove.com), we display "Mail was not sent!" and a link to index.jsp is address to start the process once again (or just open GMail.com and send the message).

mail class code: 

package quickmail;

import java.util.Date;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.Authenticator;


public class mail {

    /**
     * Outgoing Mail (SMTP) Server requires TLS or SSL: smtp.gmail.com (use
     * authentication) Use Authentication: Yes Port for SSL: 465
     */
    
     public static void sendEmail(Session session, String toEmail, String subject, String body) throws Exception {
                   
            MimeMessage msg = new MimeMessage(session);
            //set message headers
            msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
            msg.addHeader("format", "flowed");
            msg.addHeader("Content-Transfer-Encoding", "8bit");

            msg.setFrom(new InternetAddress("abc@xyz.com", "NoReply-JD"));

            msg.setReplyTo(InternetAddress.parse("abc@xyz.com", false));

            msg.setSubject(subject, "UTF-8");
 
            msg.setText(body, "UTF-8");

            msg.setSentDate(new Date());

            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
            System.out.println("\nSending Mail Now...");
            Transport.send(msg);

            System.out.println("\nEMail Sent Successfully!");
        
     }
        
    public mail(final String id, final String password, String to, String subject, String body) throws Exception
    {
        
        System.out.println("\nSSL Email [Start]");
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
        props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
        props.put("mail.smtp.socketFactory.class",
                "javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
        props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
        props.put("mail.smtp.port", "465"); //SMTP Port
        props.put("mail.smtp.connectiontimeout", "5000");
        props.put("mail.smtp.timeout", "5000");
        Authenticator auth = new Authenticator() {
            //override the getPasswordAuthentication method
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(id, password);
            }
        };

        Session session = Session.getDefaultInstance(props, auth);
        sendEmail(session, to, subject, body);
    }
}

[Note that the exceptions that indicate failure to send may occur in sendEmail function which just declared to throw the exception, all the calling functions in this code just throw the exceptions to the next class to catch. This goes all the way back to the try block in send.jsp to test whether the sending was successful or not]

I've put a tutorial on this single piece of code here. You might wanna check that out if you don't understand the things going on here.

Finally a default error page in case of unexpected errors:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Error</title>
    </head>
    <body>
        <h1>Something Went Wrong...(No one is working to fix it)</h1>
    </body>
</html>

Nothing new, just displays a nice message to the user.

If you encounter errors like javax.mail.*  -  class not found, make sure to add imports for javax.mail package, you can manually download it from the internet. Add to the project (in NetBeans) by right clicking on the project icon -> Properties -> libraries - > add JAR.

You might wanna send an E-Mail to yourself for testing.

2 comments:

  1. Replies
    1. make a class named 'message' and take three
      public class message {
      String body;
      String subject;
      String to;

      //apply getter & setter method
      }
      then run the code

      Delete