Sep 1, 2012

Form-based File Upload in J2EE Web Application Part 1

Many times we may have a file upload control on view asking user to upload a file or an image from local machine. HTML provides  a file control to upload a file. But on server side, we need to write a code to save it on a file server.

In J2EE, file upload functionality can be best achieved using Commons File Upload. A file upload request comprises an ordered list of items that are encoded according to RFC-1867. FileUpload can parse such a request and provide your application with a list of the individual uploaded items. Each such item implements the FileItem interface, regardless of its underlying implementation.

Each file item has a number of properties that might be of interest for your application. For example, every item has a name and a content type, and can provide an InputStream to access its data. On the other hand, you may need to process items differently, depending upon whether the item is a regular form field - that is, the data came from an ordinary text box or similar HTML field - or an uploaded file. The FileItem interface provides the methods to make such a determination, and to access the data in the most appropriate manner.

Before you can work with the uploaded items, of course, you need to parse the request itself. Ensuring that the request is actually a file upload request is straightforward, but FileUpload makes it simplicity itself, by providing a static method to do just that.

Let's make a very simple application to upload a file using JSP/Servlets as shown in following image.

Prerequisites


For this tutorial, we will need the following tools: (The older or newer version should also works). Moreover, basic Java knowledge is assumed.

  1. Eclipse IDE for Java EE Developers
  2. Apache Tomcat v6 or later
  3. Apache Commons IO 
  4. Apache Commons File Upload
Apache commons IO and File Upload jars has to be put in your web application lib folder. Following is the folder structure for this example.


Create a View using JSP


The view includes a simple file upload control with submit button. Following is the code:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

<form action="upload.do" method="post" enctype="multipart/form-data">
 Select file to upload: <input type="file" name="selectFile" /> <br />
 <input type="submit"> 
</form>


</body>
</html> 

 

Creating a Controller 

Controller will receive the multipart request. It will save the file at folder location configured in context parameters of the web application. It also creates a map of regular form parameters if any. We dont have any regular form parameter in this example. But that's put for your reference only.

package org.avid.upload.controller;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * @author Jay Rajani
 * 
 * Servlet implementation class UploadController
 */
public class UploadController extends HttpServlet {
 private static final long serialVersionUID = 1L;
 
 private String folderLocation = null; 
 
 @Override
 public void init() throws ServletException {
  super.init();
  this.folderLocation = getServletContext().getInitParameter("UPLOAD_FOLDER");
 }

 /**
  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  
  HashMap<String, String> formParams = new HashMap<String, String>();
  
  // Check that we have a file upload request
  boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  
  try{
   if (isMultipart){
    
    // Create a factory for disk-based file items
    FileItemFactory factory = new DiskFileItemFactory();

    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);

    // Parse the request
    List<FileItem> items = upload.parseRequest(request);
    
    // Process the uploaded items
    Iterator<FileItem> iter = items.iterator();
    while (iter.hasNext()) {
        FileItem item = (FileItem) iter.next();

        if (item.isFormField()) {
         
         // Process a regular form field
         formParams.put(item.getFieldName(), item.getString());
        } else {
         
         // Process a file upload
         String fileName = item.getName();
         
         File uploadedFile = new File(folderLocation+File.separator+fileName);
            item.write(uploadedFile);
        }
    }
   }
  }catch(FileUploadException fue){
   fue.printStackTrace();
   throw new ServletException(fue.getMessage());
  }catch(Exception e){
   e.printStackTrace();
   throw new ServletException(e.getMessage());
  }
 }

}


Deployment Descriptor


Here is the snippet of final deployment descriptor.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 <context-param>
  <param-name>UPLOAD_FOLDER</param-name>
  <param-value>E:/temp</param-value>
 </context-param>
 
 <display-name>FileUpload</display-name>
 
 <servlet>
  <description>
  </description>
  <display-name>UploadController</display-name>
  <servlet-name>UploadController</servlet-name>
  <servlet-class>
  org.avid.upload.controller.UploadController</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>UploadController</servlet-name>
  <url-pattern>/upload.do</url-pattern>
 </servlet-mapping>

</web-app>

The code will save the file to location specified in web.xml. It can be a local folder or shared folder or ftp location depending on your requirement.

Aug 28, 2012

Step by step guide - Developing a MVC application using J2EE and MySQL


In this tutorial, we will create a simple J2EE application that performs CRUD (Create Read Update Delete) operations for User Management using Jsp, Servlet and MySQL.


Prerequisites


For this tutorial, we will need the following tools: (The older or newer version should also works). Moreover, basic Java knowledge is assumed.


  1. Eclipse IDE for Java EE Developers
  2. Apache Tomcat v6 or later
  3. MySQL Community Server and MySQL Workbench (GUI Tool)
  4. MySQL Connector for Java
  5. jstl.jar and standard.jar
You can get the required jars from your Tomcat. Check in this directory : (your tomcat directory)—>apache-tomcat-7.0.26-windows-x86—>apache-tomcat-7.0.26—>webapps—>examples—>WEB-INF—>lib

I will tell you where you should put these jars later.

jQuery for javascript capability. In this case, we only use it for the datepicker component

Create the database


First, lets create the database and table for User using the following SQL scripts:

create database UserDB;
use UserDB;
grant all on UserDB.* to 'admin'@'localhost' identified by 'test';

CREATE TABLE UserDB.`users` (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `lastname` varchar(45) DEFAULT NULL,
  `dob` date DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8


Setting up Eclipse and Tomcat


Go to eclipse. Before we create a new project for our application, we need to setup the server. Select File—>New—>Other. From the tree, Select Server.

Choose Apache—>Tomcat v7.0 Server and set the runtime environment.

Next, create a new project. Select File—>New—>Dynamic Web Project.

Enter “SimpleJspServletDB” as the project name. Select target runtime to Apache Tomcat v7.0 which we already setup before. Click Finish.

Copy the standard.jar, mysql-connector jar and jstl jar to WEB-INF—>lib folder.

Creating Package structure


Create four packages in the src folder.
  • org.avid.controller: contains the servlets
  • org.avid.dao: contains the logic for database operation
  • org.avid.model: contains the POJO (Plain Old Java Object). Each class in this package represents the database table. For this tutorial, however, we only have one table.
  • org.avid.util : contains the class for initiating database connection

Creating Model - POJOs


Next, create a new Java class. in org.avid.model folder. Name it “User.java” and insert these following codes. Each of the variables in this class represents the field in USERS table in our database.

package org.avid.model;

import java.util.Date;

public class User {

    private int userid;
    private String firstName;
    private String lastName;
    private Date dob;
    private String email;
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Date getDob() {
        return dob;
    }
    public void setDob(Date dob) {
        this.dob = dob;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User [userid=" + userid + ", firstName=" + firstName
                + ", lastName=" + lastName + ", dob=" + dob + ", email="
                + email + "]";
    }  
}

Creating DB Connection Utility


Create a new class in org.avid.util package and name it DbUtil.java. This class handles the database connection to our MySQL server. In this class, we read a .properties file which contains the information necessary for the connection.

package org.avid.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DbUtil {

    private static Connection connection = null;

    public static Connection getConnection() {
        if (connection != null)
            return connection;
        else {
            try {
                Properties prop = new Properties();
                InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("/db.properties");
                prop.load(inputStream);
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("user");
                String password = prop.getProperty("password");
                Class.forName(driver);
                connection = DriverManager.getConnection(url, user, password);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return connection;
        }

    }
}

Create the properties file directly under the src folder. Create a new file, name it db.properties. Put the following information inside.

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
user=admin
password=test

Creating Data Access Object (DAO)


Next, create a new class in org.avid.dao package, name it UserDao.java. Dao stands for Data Access Object. It contains the logic for  database operation.

package org.avid.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.avid.model.User;
import org.avid.util.DbUtil;

public class UserDao {

    private Connection connection;

    public UserDao() {
        connection = DbUtil.getConnection();
    }

    public void addUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("insert into users(firstname,lastname,dob,email) values (?, ?, ?, ? )");
            // Parameters start with 1
            preparedStatement.setString(1, user.getFirstName());
            preparedStatement.setString(2, user.getLastName());
            preparedStatement.setDate(3, new java.sql.Date(user.getDob().getTime()));
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void deleteUser(int userId) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("delete from users where userid=?");
            // Parameters start with 1
            preparedStatement.setInt(1, userId);
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void updateUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("update users set firstname=?, lastname=?, dob=?, email=?" +
                            "where userid=?");
            // Parameters start with 1
            preparedStatement.setString(1, user.getFirstName());
            preparedStatement.setString(2, user.getLastName());
            preparedStatement.setDate(3, new java.sql.Date(user.getDob().getTime()));
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.setInt(5, user.getUserid());
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    public List<User> getAllUsers() {
        List<User> users = new ArrayList<User>();
        try {
            Statement statement = connection.createStatement();
            ResultSet rs = statement.executeQuery("select * from users");
            while (rs.next()) {
                User user = new User();
                user.setUserid(rs.getInt("userid"));
                user.setFirstName(rs.getString("firstname"));
                user.setLastName(rs.getString("lastname"));
                user.setDob(rs.getDate("dob"));
                user.setEmail(rs.getString("email"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return users;
    }

    public User getUserById(int userId) {
        User user = new User();
        try {
            PreparedStatement preparedStatement = connection.
                    prepareStatement("select * from users where userid=?");
            preparedStatement.setInt(1, userId);
            ResultSet rs = preparedStatement.executeQuery();

            if (rs.next()) {
                user.setUserid(rs.getInt("userid"));
                user.setFirstName(rs.getString("firstname"));
                user.setLastName(rs.getString("lastname"));
                user.setDob(rs.getDate("dob"));
                user.setEmail(rs.getString("email"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return user;
    }
}


Creating Contrrollers


Finally, create a new Servlet inside the org.avid.controller package and name it UserController.java

package org.avid.controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.avid.dao.UserDao;
import org.avid.model.User;

public class UserController extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static String INSERT_OR_EDIT = "/user.jsp";
    private static String LIST_USER = "/listUser.jsp";
    private UserDao dao;

    public UserController() {
        super();
        dao = new UserDao();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String forward="";
        String action = request.getParameter("action");

        if (action.equalsIgnoreCase("delete")){
            int userId = Integer.parseInt(request.getParameter("userId"));
            dao.deleteUser(userId);
            forward = LIST_USER;
            request.setAttribute("users", dao.getAllUsers());  
        } else if (action.equalsIgnoreCase("edit")){
            forward = INSERT_OR_EDIT;
            int userId = Integer.parseInt(request.getParameter("userId"));
            User user = dao.getUserById(userId);
            request.setAttribute("user", user);
        } else if (action.equalsIgnoreCase("listUser")){
            forward = LIST_USER;
            request.setAttribute("users", dao.getAllUsers());
        } else {
            forward = INSERT_OR_EDIT;
        }

        RequestDispatcher view = request.getRequestDispatcher(forward);
        view.forward(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = new User();
        user.setFirstName(request.getParameter("firstName"));
        user.setLastName(request.getParameter("lastName"));
        try {
            Date dob = new SimpleDateFormat("MM/dd/yyyy").parse(request.getParameter("dob"));
            user.setDob(dob);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        user.setEmail(request.getParameter("email"));
        String userid = request.getParameter("userid");
        if(userid == null || userid.isEmpty())
        {
            dao.addUser(user);
        }
        else
        {
            user.setUserid(Integer.parseInt(userid));
            dao.updateUser(user);
        }
        RequestDispatcher view = request.getRequestDispatcher(LIST_USER);
        request.setAttribute("users", dao.getAllUsers());
        view.forward(request, response);
    }
}

Creating View


Now, it’s time for us to create the jsp, the view for our application. Under the WebContent folder, create a jsp file, name it index.jsp


<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<jsp:forward page="/UserController?action=listUser" />
</body>
</html>

This jsp serves as the entry point for our application. In this case, it will redirect the request to our servlet to list all the users in the database.

Next, create the jsp to list all the users in the WebContent folder. Name it listUser.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Show All Users</title>
</head>
<body>
    <table border=1>
        <thead>
            <tr>
                <th>User Id</th>
                <th>First Name</th>
                <th>Last Name</th>
                <th>DOB</th>
                <th>Email</th>
                <th colspan=2>Action</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${users}" var="user">
                <tr>
                    <td><c:out value="${user.userid}" /></td>
                    <td><c:out value="${user.firstName}" /></td>
                    <td><c:out value="${user.lastName}" /></td>
                    <td><fmt:formatDate pattern="yyyy-MMM-dd" value="${user.dob}" /></td>
                    <td><c:out value="${user.email}" /></td>
                    <td><a href="UserController?action=edit&userId=<c:out value="${user.userid}"/>">Update</a></td>
                    <td><a href="UserController?action=delete&userId=<c:out value="${user.userid}"/>">Delete</a></td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    <p><a href="UserController?action=insert">Add User</a></p>
</body>
</html>

In this jsp, we use JSTL to connect between the jsp and the servlet. We should refrain from using scriplet inside the jsp because it will make the jsp more difficult to maintain. Not to mention it will make the jsp looks ugly.

Next, create a new jsp in WebContent folder and name it user.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<link type="text/css"
    href="css/ui-lightness/jquery-ui-1.8.18.custom.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.18.custom.min.js"></script>
<title>Add new user</title>
</head>
<body>
    <script>
        $(function() {
            $('input[name=dob]').datepicker();
        });
    </script>

    <form method="POST" action='UserController' name="frmAddUser">
        User ID : <input type="text" readonly="readonly" name="userid"
            value="<c:out value="${user.userid}" />" /> <br />
        First Name : <input
            type="text" name="firstName"
            value="<c:out value="${user.firstName}" />" /> <br />
        Last Name : <input
            type="text" name="lastName"
            value="<c:out value="${user.lastName}" />" /> <br />
        DOB : <input
            type="text" name="dob"
            value="<fmt:formatDate pattern="MM/dd/yyyy" value="${user.dob}" />" /> <br />
        Email : <input type="text" name="email"
            value="<c:out value="${user.email}" />" /> <br /> <input
            type="submit" value="Submit" />
    </form>
</body>
</html>


Deployment Descriptor



Lastly, check the web.xml file located in WebContent—>WEB-INF folder in your project structure. Make sure it looks like this

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SimpleJspServletDB</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>UserController</display-name>
    <servlet-name>UserController</servlet-name>
    <servlet-class>org.avid.controller.UserController</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserController</servlet-name>
    <url-pattern>/UserController</url-pattern>
  </servlet-mapping>
</web-app>

That is it. Right click the project name and run it using Run As–>Run on server option.

Aug 19, 2012

JavaMail API Part 4 - Using secured protocol

There are many security measures we can implement into the system. We will take a special case of gmail which uses STARTTLS. STARTTLS is an extension to plain text communication protocols, which offers a way to upgrade a plain text connection to an encrypted (TLS or SSL) connection instead of using a separate port for encrypted communication.



Here is the code for sending email using host which implements STARTTLS.

package com.test;

import java.util.Properties;

import javax.activation.DataHandler;

import javax.activation.DataSource;

import javax.activation.FileDataSource;

import javax.mail.Message;

import javax.mail.MessagingException;

import javax.mail.Multipart;

import javax.mail.Session;

import javax.mail.Transport;

import javax.mail.internet.AddressException;

import javax.mail.internet.InternetAddress;

import javax.mail.internet.MimeBodyPart;

import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMultipart;


public class SendMail {

   public static void main(String[] args) {

      String host = "smtp.gmail.com";

      String from = "sender@gmail.com";

      String pass = "sender's password";

      Properties props = System.getProperties();

      props.put("mail.smtp.starttls.enable", "true"); // added this line

      props.put("mail.smtp.host", host);

      props.put("mail.smtp.user", from);

      props.put("mail.smtp.password", pass);

      props.put("mail.smtp.port", "587");

      props.put("mail.smtp.auth", "true");

      String[] to = {"recipient1@abc.com, recipient2@abc.com"};

      String fileAttachment = "F:\\emoticons\\yawn.gif";

      Session session = Session.getDefaultInstance(props, null);

      MimeMessage message = new MimeMessage(session);

      try {

         message.setFrom(new InternetAddress(from));

         InternetAddress[] toAddress = new InternetAddress[to.length];

         // To get the array of addresses

         for( int i=0; i < to.length; i++ ) { // changed from a while loop

            toAddress[i] = new InternetAddress(to[i]);

         }

         for( int i=0; i < toAddress.length; i++) { // changed from a while loop

            message.addRecipient(Message.RecipientType.TO, toAddress[i]);

         }

         message.setSubject("sending in a group");

         // create the message part 

         MimeBodyPart messageBodyPart = new MimeBodyPart();

         //fill message

         messageBodyPart.setText("Hi");

         Multipart multipart = new MimeMultipart();

         multipart.addBodyPart(messageBodyPart);

         // Part two is attachment

         messageBodyPart = new MimeBodyPart();

         DataSource source = new FileDataSource(fileAttachment);

         messageBodyPart.setDataHandler(new DataHandler(source));

         messageBodyPart.setFileName(fileAttachment);

         multipart.addBodyPart(messageBodyPart);

         // Put parts in message

         message.setContent(multipart);

         Transport transport = session.getTransport("smtp");

         transport.connect(host, from, pass);

         transport.sendMessage(message, message.getAllRecipients());

         transport.close();

      } catch (AddressException e) {

         e.printStackTrace();

      } catch (MessagingException e) {

         e.printStackTrace();

      }
   }
}

JavaMail API Part 3 - Send attachment in email


Here is an example to send an email with attachment from your machine.

We assume that mail server is running on localhost and is connected to internet to send email.



For prerequisites please refer to my previous article on JavaMail API.


// File Name SendFileEmail.java



import java.util.*;

import javax.mail.*;

import javax.mail.internet.*;

import javax.activation.*;



public class SendFileEmail

{

   public static void main(String [] args)

   {

    

      // Recipient's email ID needs to be mentioned.

      String to = "abcd@gmail.com";

      // Sender's email ID needs to be mentioned

      String from = "web@gmail.com";

      // Assuming you are sending email from localhost

      String host = "localhost";

      // Get system properties

      Properties properties = System.getProperties();

      // Setup mail server

      properties.setProperty("mail.smtp.host", host);

      // Get the default Session object.

      Session session = Session.getDefaultInstance(properties);

      try{
         // Create a default MimeMessage object.

         MimeMessage message = new MimeMessage(session);

         // Set From: header field of the header.

         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.

         message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

         // Set Subject: header field

         message.setSubject("This is the Subject Line!");

         // Create the message part

         BodyPart messageBodyPart = new MimeBodyPart();

         // Fill the message

         messageBodyPart.setText("This is message body");

        

         // Create a multipar message

         Multipart multipart = new MimeMultipart();

         // Set text message part

         multipart.addBodyPart(messageBodyPart);

         // Part two is attachment

         messageBodyPart = new MimeBodyPart();

         String filename = "file.txt";

         DataSource source = new FileDataSource(filename);

         messageBodyPart.setDataHandler(new DataHandler(source));

         messageBodyPart.setFileName(filename);

         multipart.addBodyPart(messageBodyPart);

         // Send the complete message parts

         message.setContent(multipart );

         // Send message

         Transport.send(message);

         System.out.println("Sent message successfully....");

      }catch (MessagingException mex) {

         mex.printStackTrace();

      }

   }

}



Compile and run this program to send an HTML email:

$ java SendFileEmail

Sent message successfully....



User Authentication


If it is required to provide user ID and Password to the email server for authentication purpose then you can set these properties as follows:

props.setProperty("mail.user", "myuser");

props.setProperty("mail.password", "mypwd");



Rest of the email sending mechanism would remain as explained above.

JavaMail API Part 2 - Sending rich text in email

We send simple text in email in previous post in the series. In this article, we will send rich text. For rich text, MIME type is "text/html". The actual mail content is written in HTML. While sending email, HTML contents will be set and content type is set to "text/html".

We assume that mail server is running on localhost and is connected to internet to send email.

For prerequisites please refer to my previous article on JavaMail API.


Using this example, you can send as big as HTML content you like.

// File Name SendHTMLEmail.java

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

public class SendHTMLEmail
{
   public static void main(String [] args)
   {
     
      // Recipient's email ID needs to be mentioned.
      String to = "abcd@gmail.com";
      // Sender's email ID needs to be mentioned
      String from = "web@gmail.com";
      // Assuming you are sending email from localhost
      String host = "localhost";
      // Get system properties
      Properties properties = System.getProperties();
      // Setup mail server
      properties.setProperty("mail.smtp.host", host);
      // Get the default Session object.
      Session session = Session.getDefaultInstance(properties);
      try{
         // Create a default MimeMessage object.
         MimeMessage message = new MimeMessage(session);
         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));
         // Set To: header field of the header.
         message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
         // Set Subject: header field
         message.setSubject("This is the Subject Line!");
         // Send the actual HTML message, as big as you like
         message.setContent("<h1>This is actual message</h1>", "text/html" );
         // Send message
         Transport.send(message);
         System.out.println("Sent message successfully....");
      }catch (MessagingException mex) {
         mex.printStackTrace();
      }
   }
}
Compile and run this program to send an HTML email:

$ java SendHTMLEmail
Sent message successfully....

Aug 18, 2012

JavaMail API Part 1 - Sending simple text email

There are many applications where system has to send an email to the user.
  • Notification
  • Validation
  • Reporting
  • Alarming etc
Sending email though look simple but it has many things to be considered like 
  • Whether email is a rich text or simple text
  • Whether email has attachment
  • Email using authentication
  • Emailing using secured protocols and mechanisms
Let's first take a simple case of sending a simple text email. We can write a simple standalone java application to send email. 

Prerequisites


We will need  JavaMail API and Java Activation Framework (JAF). You can download latest version from Oracle website.

Download and unzip these files, in the newly created top level directories you will find a number of jar files for both the applications. You need to add mail.jar and activation.jar files in your CLASSPATH.

We will also need mail server to send an email. There are many open source mail server we can use or we can use inbuilt mail server from operating system. Let's assume that mail server is running on localhost.

Sending Text Email


Following is the code.

// File Name SendMail.java

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

public class SendMail
{
   public static void main(String [] args)
   {    
      // Recipient's email ID needs to be mentioned.
      String to = "abcd@gmail.com";
      // Sender's email ID needs to be mentioned
      String from = "web@gmail.com";
      // Assuming you are sending email from localhost
      String host = "localhost";
      // Get system properties
      Properties properties = System.getProperties();
      // Setup mail server
      properties.setProperty("mail.smtp.host", host);
      // Get the default Session object.
      Session session = Session.getDefaultInstance(properties);
      try{
         // Create a default MimeMessage object.
         MimeMessage message = new MimeMessage(session);
         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));
         // Set To: header field of the header.
         message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
         // Set Subject: header field
         message.setSubject("This is the Subject Line!");
         // Now set the actual message
         message.setText("This is actual message");
         // Send message
         Transport.send(message);
         System.out.println("Sent message successfully....");
      }catch (MessagingException mex) {
         mex.printStackTrace();
      }
   }
}

Compile and run this program to send a simple email:

$ java SendMail
Sent message successfully....


Sending Email to multiple recipient


If you want to send an email to multiple recipients then following methods would be used to specify multiple email IDs:

void addRecipients(Message.RecipientType type, Address [] addresses) MessagingException

Here is the description of the parameters:

  • type: This would be set to TO, CC or BCC. Here CC represents Carbon Copy and BCC represents Black Carbon Copy. Example Message.RecipientType.TO
  • addresses: This is the array of email ID. You would need to use InternetAddress() method while specifying email IDs

Jul 19, 2012

Installing mysql on Red Hat

To install mysql on linux, we need RPM files. You can download MySQL-5.5.20-1.linux2.6.i386.tar from mysql download page to understand and try steps from this article.

For standard installation, one needs to install two RPMs: Server and Client. Server RPM contains mysql database, services, daemons etc whereas Client RPM contains admin tools, querying tools etc.

In MySQL-5.5.20-1.linux2.6.i386.tar file, you will get following required RPMs

MySQL-server-5.5.20-1.linux2.6.i386.rpm
MySQL-client-5.5.20-1.linux2.6.i386.rpm

In my machine, I have downloaded RPMs on in /bin folder. Now go to shell and change directory to bin.

[root@mysql bin]# rpm -ivf MySQL-server-5.5.20-1.linux2.6.i386.rpm

This will install server RMPs without setting password for root user causing anonymous access. To change the password you will need mysqladmin. It is bundled in client RPM.

[root@mysql bin]# rpm -ivf MySQL-client-5.5.20-1.linux2.6.i386.rpm

After successful installation run following command to change root password

[root@mysql bin]# /usr/bin/mysqladmin -u root password 'new-password'

Now your mysql is ready to run. But the moment you try to connect it will give error like " is not allowed to connect to mysql service"

The issue is caused because of default privileges given to root user. You need connect privilege to connect from a remote machine. You can grant all privileges to root user.

[root@mysql bin]# su - mysql

This will open bash for mysql user created when you install server RPMs.

-bash-3.2$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.5.20 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

mysql> GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '';
Query OK, 0 rows affected (0.00 sec)


Now try connecting the mysql server, you should be able to connect.

For unlucky people like me :), things do not start easily. When I tried installing mysql for the first time, mysqld service could not start. If the same thing happens to you, first check your installed packages using following command

[root@mysql bin]# rpm -qa | grep 'MySQL'
MySQL-server-5.5.20-1.linux2.6
MySQL-client-5.5.20-1.linux2.6

If you can see both RPM, you are okay with installation or nothing has been uninstalled. If it does not show you both, you need to install the required RPM.

Second step is to find mysqld and provide privilege using

[root@mysql bin]# chmod 775 mysqld

and then

[root@mysql bin]# service mysqld start

You can also start it using

[root@mysql bin]# /usr/bin/mysqld_safe &

That's it. There can be a lot of difference in issues faced while installing. Linux requires a thorogh understanding of how different flavour of linux works. But as programmers we can use google to stay away from that burden.

You can share your experiences here if you wish to.

Jun 30, 2012

Writing centralized validation using Java Annotation Part 1

The validation component in any application is generally scattered on different layers, though it is not a good practice. On presentation tier we have JS validations and on JSP/ Servlet side we use some POJO stuff. Again if we reach at persistence layer we have hibernate validation or any other db validations. As it is described here and we can realize. Many times validations has been performed at each class level without any code reuse.

The issue is in the architecture. We need to design a clear cut architecture for validation component. We have to identify entities to be validated, kind of business rules to be applied etc. Some entity has to be validated differently for different groups. e.g. User entity - when we receive request we see for values other than id, but while inserting into db we validate id. Similarly multiple flows use the same entity differently. Hence centralizing validation component is not again a simple job.

Here in this series, I will explain you how to achieve the goal at certain extent using Java annotation and hibernate validation. The mechanism may be different for different application.

Let's start with a centralized validator class using annotation

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

// default validator is required as per JSR303. We have hibernate validator jar for the same.
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

Set<ConstraintViolation<Object>> constraintViolations = validator.validate(targetObject);

if (constraintViolations.size() > 0) {
for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
// Actions to be taken when validation fails
throw new RuntimeException(constraintViolation.getMessage());
}
}
ValidatorFactory is a factory class found in the implementation jar. We hibernate validation. You can refer Java Validation API. It searches for classes which implements
javax.validation.ConstraintValidator.
Here is an example of such a validator which validates a POJO say it Task

package com.avid.validation.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.avid.transfer.Task;
import com.avid.validation.annotation.ValidateTask;

public class TaskValidator implements ConstraintValidator<ValidateTask, Task> {

@Override
public void initialize(ValidateTask validateTask) {}

@Override
public boolean isValid(Task task, ConstraintValidatorContext validationContext) {
if(task == null || task.getId() == -1) {
validationContext.disableDefaultConstraintViolation();
validationContext.buildConstraintViolationWithTemplate("No task selected.").addConstraintViolation();
return false;
}
return true;
}
}
When we call validator.validate(targetObject), javax.validation.Validator first finds suitable validator for object passed in the argument using its class name. It calles initialize method to initialize properties and resources. At last it will call isValid method.
You must be wondering about ValidateTask. It is an annotation used to specify where to perform the validation. Following is the code for ValidateTask

@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=TaskValidator.class)
public @interface ValidateTask {

// All three properties are required by validation framework
String message() default "{TaskValidator}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
You can use it at class level or instance level. For this example I have used it at class level for simplicity like

@ValidateTask
public class Task extends BaseVO {
private int id;
private String taskName;

...........
}
Now we are done with centralized validator for Task. We can extend it to any number of entities. To use the validator in client, now you need only one line

 DefaultValidator.validate(new Task())
That's it. Now you can modify at one place and can impact entire application without the hassle of finding validation code and fixing it at multiple places.

In next article I will show you how to add Regex validator and db validator in the same component to make it robust.