Thursday, 26 June 2014

Creating new developer profile on firefox using profilemanager.

Background

It all started when I thought of creating an addon for firefox. Basic setup requires you to set up a new profile to work on. I am not sure why this feature is known to few people developing addons for firefox. Basically you can create multiple profiles in firefox. That means if you  are sharing your computer with some other person you can have two different firefox profiles for each. Each profile has its own bookmarks, active logons etc. Both are mutually exclusive.

Logged into GMail? and friend wants to see his mail ? Use different profile. Keep one profile fixed for yourself.

So lets see how this is done.

Getting Started

  1. Make sure there are no instances of firefox running or the below command won't work.
  2. First add your firefox to your PATH environment variable (It is not necessary but if you are planning for experimenting with firefox like me I would suggest go ahead and do it.)

  3. Next open your command prompt and type
    'firefox --profilemanager'.
    That should open a profile manager. In that you can create a new profile. I have named it 'developer'.

  4. Once created you can launch any profile by the command
    'firefox -p developer'.
    If you want to run two profiles together you can do
    'firefox -no-remote -p default'.
    You need to use 'no-remote' argument.

  5. You can also take backup up your profiles using MozBackup . You can download it from here.

Thats it with setting up the profile. If you only want to have exclusive profiles for use you are good with above. If you want to explore further look below -

Developer configurations

If you are looking ahead to  develop for mozilla firefox then you may want to set up certain configuration properties.

Open your browser with developer profile and enter 
about:config
in the address bar. You should see the following screen - 


Go ahead and select "I promise!" :). You should then get access to advanced configurations.


Set the properties as described in the Setting up an extension development environment.



Wednesday, 25 June 2014

How to display processing during Ajax request processing using jQuery

Goal

User interaction is very crucial. When you are making ajax calls to the server and response takes some time your webpage looks like hanged and user is clueless so as to what is happening. So it is a good approach to show some animated icon on the page during the request processing so that user can understand that the precessing is in progress.


On to the code.....

First, create an Ajax icon using the AjaxLoad site.

Then add the following to your HTML:

<img src="/images/loading.gif" id="loading-indicator" style="display:none" />

And the following to your CSS file:
#loading-indicator {
  position: absolute;
  left: 10px;
  top: 10px;
}


Lastly, you need to hook into the Ajax events that jQuery provides; one event handler for when the Ajax request begins, and one for when it ends:

$(document).ajaxSend(function(event, request, settings) {
  $('#loading-indicator').show();
});

$(document).ajaxComplete(function(event, request, settings) {
  $('#loading-indicator').hide();
});

Taken from source.

How to Use JSON Objects With Twitter Bootstrap Typeahead

Background

Bootstrap is a free collection of tools for creating websites and web applications. It contains HTML and CSS-based design templates for typography, forms, buttons, navigation and other interface components, as well as optional JavaScript extensions. (More on Wiki).

You can visit their official site for more details. You need to download it and add the css file and javascript file to your project. In this post i am going to cover how can we use JSON Object to autocomplete text fields.




To the Code.....

Add the following in your java script. You can put all typeahead calls in a single function and then call that function from your javascript in the HTML (or JSP) page.

var states = [];
var    map = {};
$('#search').typeahead({

    minLength: 0,

    source : function(query, process) {        

        states = [];

        map = {};
        //hardcoding this JSON but this would technically come from server
        var data = [
        {"stateCode": "CA", "stateName": "California"},
        {"stateCode": "AZ", "stateName": "Arizona"},
        {"stateCode": "NY", "stateName": "New York"},
        {"stateCode": "NV", "stateName": "Nevada"},
        {"stateCode": "OH", "stateName": "Ohio"}
    ];

    $.each(data, function (i, state) {
        map[state.stateName] = state;
        states.push(state.stateName);
    });

    process(states);
    },
    matcher: function (item) {
        //If user enters * show all possible entries
        if(this.query.trim().toLowerCase() == "*") {
            return true;
        }
        if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
            return true;
        }
    },
    updater: function (item) {
        //If you want to do something prior to updating value 
        selectedState = map[item].stateCode;
        return item;
    },
    sorter: function (items) {
        return items.sort();
    },
    highlighter: function (item) {
       // implementation
    },

});

Also you can override your typeahead class as follows for better looks

.typeahead {
max-height: 200px;
overflow-y: auto;
overflow-x: hidden;
}


Thats it for the autocomplete feature of twitter bootstrap. You can make ajax call to get the JSON data as follows

function getData(url, data, successCallback, errorCallback) {
    var requestType = "POST";
    var dataType = "json";
    make_ajax_call(url, data, requestType, dataType, successCallback, errorCallback);
}

function make_ajax_call(url, data, requestType, dataType, successCallback, errorCallback) {
    
    var request = {
        url : url,
        type : requestType,
        data : data,
        dataType : dataType,
        success : successCallback,
        error : errorCallback,
        async : false
    };
    jQuery.ajax(request);

}
You can import jquery using

<script src="http://code.jquery.com/jquery.js"></script>

Monday, 23 June 2014

NodeJS Hello World Example.

Background

As Wiki says

“Node.js is a packaged compilation of Google’s V8 JavaScript engine, the libuv platform abstraction layer, and a core library, which is itself primarily written in JavaScript.”

Node.js applications are designed to maximize throughput and efficiency, using non-blocking I/O and asynchronous events. Node.js applications run single-threaded, although Node.js uses multiple threads for file and network events. Node.js is commonly used for real time applications due to its asynchronous nature, allowing applications to display information faster for users without the need for refreshing.

How it Works?

Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. 

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Getting Started

  1. First step would be to download the Node.js application. You can download the installer from the official site. Add the executable to the class path. If in windows add it to the %PATH% environment variable. If using linux you can set in your .profile file and export it.
  2. To test whether it is properly added to the PATH you can simply open the command prompt and type node -v  : It should give you the version you are using.

  3. Next lets get directly to the code. Open your favorite text editor (Notepad, gedit, vi, emacs .. whatever you like) and paste in the following code

        var http = require('http');
        http.createServer(function (req, res) {
          res.writeHead(200, {'Content-Type': 'text/plain'});
          res.end('Hello World\n');
        }).listen(1337, "127.0.0.1");
        console.log('Server running at http://127.0.0.1:1337/');
    


    Then save the file  with .js extension. I am saving it as hw.js (representing helloworld.js).
  4. And that's it. Lets execute our code. Again open command prompt where your hw.js file is located and run command `node hw.js`. This would start your server.

  5. Finally you can check in your browser by typing the URL http://localhost:1337. You should see "Hello World!"

It is that simple to write applications in NodeJS.

Installing NPM

NPM is Node Package manager. You will need this too for installing different modules.  So download the NPM zip file from node.js site  . Extract it in the same folder as that of node installer . Also remember we had added that directory in the PATH env variable so even npm command should be valid in console. You can try that out by typing npm in the cmd. You should see the usage. You can also try installing a package.

npm install express -g


You can see the module installed in NodeJS\node_modules where NodeJS is the directory which has the node installer in it.

Important Links

Sunday, 22 June 2014

Supporting https URLs on your Tomcat server.

Goal

Couple of posts back we saw how we can write a normal server in Spring MVC ( Spring MVC Hello Wold Example  ). If you notice the URL was something like "http://localhost:8080/GreeterProject/welcome.htm". Notice the protocol used is http. But you must have seen some sites using a more secure protocol called https. Specially sites which have payment transactions. In this post we will see how can we support those. So by the end of this post we should be able to hit URL like "https://localhost/GreeterProject/welcome.htm".

Prerequisite

For this post I am assuming you have the setup equivalent to how the setup at the end of post Spring MVC Hello Wold Example  . Also you should have Java SDK with you. We will need it ti create a self signed certificate which is essential for SSL connections (https). Do not worry about it as of now. Just make sure you have Java SDK installed.

Basics

SSL (and its successor, TLS) is a protocol that operates directly on top of TCP (although there are also implementations for datagram based protocols such as UDP). This way, protocols on higher layers (such as HTTP) can be left unchanged while still providing a secure connection. Underneath the SSL layer, HTTP is identical to HTTPS.

When using SSL/TLS correctly, all an attacker can see on the cable is which IP and domain you are connected to, roughly how much data you are sending, and what encryption and compression is used. He can also terminate the connection, but both sides will know that the connection has been interrupted by a third party.

Getting Started

So lets get started. First lets edit the configuration for the Apache tomcat server so that it can now support SSL(https) connections.

Go to server.xml file . If you are using Eclipse IDE then there should be a separate folder created for servers in the projects directory. In that you will have multiple servers (you have configured) configurations. If you see the previous post on how to create a simple Hello World Spring MVC project we create a new server instance to run it on. That would be present in that servers folder. If not when you run your project by selecting run as -> Run on server Eclipse will ask you to configure one. 

If you are using plain Apache tomcat installation i.e no eclipse then you can find this file in path TomcatInstallation/conf/server.xml . Here TomcatInstallation is the folder where you have installed tomcat.

In this file you would see a commented line like

<Connector SSLEnabled="true" clientAuth="false"  maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/>

It would be commented. You can see <!-- --> tags. Remove them i.e un-comment it. You need to add some more properties like keystoreFile and keystorePass. The line should now look like

<Connector SSLEnabled="true" clientAuth="false" keystoreFile="${user.home}/.keystore" keystorePass="mypasswd" maxThreads="150" port="443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/>

Do not worry about keystoreFile and keystorePass. I will come to it. Notice other than that I have changed the port from 8443 to 443. You can leave it at 8443 but 443 is the default port for SSL. So I used it. If you change this you don't have to explicitly add a port in your URL.

You can view your server config from Eclispe itself. Double click your server in servers tab.


Understanding and Creating a keystore

For secure connection between server and client (browser in this case) server needs to send a certificate signed by some trusted authority. Client must trust the authority who has signed this certificate. What are the contents of the certificate, how client knows that the certificate comes from the proper server etc questions are out of scope for this discussion. If interested you can go through the Important links section at the bottom of this post. 

Important point is we need a certificate on server. For demonstration purpose i am going to create a self signed certificate and use it. Yes when browser hits this URL it would not be something broweser automatically trusts so we would have to give permission to the browser to trust it. But we can see that later. Create a self signed certificate. You can go through my earlier post on it ( Creating a self signed certificate for SSL using java keytool ) .  This will be created in your root folder with name .keystore. Now if you looks back at the configuration changes we made in tomcat server.xml file keystoreFile is the path to this certificate and keystorePass is the password you used while creating the certificate.


That's it start the server now. You should get screen like below.


Go ahead select "I Understand the Risks" and select "Add Exception". You will again get a popup screen to conform security Exception. You can also View the details of the certificate by clicking View Details.



After you select conform security Exception you can see your webpage with https.




And you are done :) Let me know if you still have any question.

Important Links

Creating a self signed certificate for SSL using java keytool

Goal

In this post we will see how to create a self signed certificate using keytool  utility provided in java SDK. You should have Java SDK installed for this and set it in the classpath.  Simplesway to check if it is added in the classpath is to open command prompt and type java -version. It should show you which java version you are using.



Getting Started

So lets get started.

  1. Run the following command from the command line -

    keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass mypasswd -validity 360 -keysize 2048
    
  2. You will be asked to enter some details. Enter your first and last name (same line).
  3. Then enter your organizational unit name.
  4. Then name of your city / locality.
  5. Name of your state / province.
  6. Two letter country code.
  7. And finally the key password. Hit enter if it is same as keystore password.

 Your keystore.jks should be create in your root folder or the PATH (if you have explicitly provided one).


 

More Details...


To create a new keystore from scratch, containing a single self-signed Certificate, execute the following from a terminal command line:

Windows:
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA   

Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA


Note 1 : The RSA algorithm should be preferred as a secure algorithm, and this also ensures general compatibility with other servers and components.

Note 2 : This command will create a new file, in the home directory of the user under which you run it, named ".keystore". To specify a different location or filename, add the -keystore parameter, followed by the complete pathname to your keystore file, to the keytool command shown above.

For detailed post on how to configure and support https on your tomcat refer following -

Important Links

Thursday, 19 June 2014

How to enable developers option in your android device?

I really though they are enabled by default but as it turns out it is not. And why should it be ? It of no use for a normal android smart phone user. Why would be care is USB debugging is enabled or not? But we as a developers do. So lets see hoe we can enable developer mode in android.

  1. Go to System Settings - > About Phone
  2. You will see Build number listed there.
  3. Tap on it about 7 times and you must see a toast saying "Developers mode is turned on".
  4. Then developers options should be available in your System Settings.








Then you can view all your Developer options including enabling/disabling USB debugging.

Wednesday, 18 June 2014

How to run adb shell always as a root?

 Goal

How can we run adb shell every time with root permissions. Procedure is shown below.

You can try this method, but be carefully as this allows any app to gain root access. You can say this may led to "Security Hole!"

Procedure


Make your suid binary insecure by typing the following commands.

  1. Go to platform-tools directory inside sdk folder.
  2. Open command prompt in that directory and execute following commands.
  3. adb shell
  4. su
    User will be prompted to grant super user privileges to adb shell.

  5. mount -o remount,rw /system (or: adb remount)
  6. ls -la /system/bin/sh (Observer the output)
  7. chmod 4755 /system/bin/sh
  8. ls -la /system/bin/mksh (Again observe the output. Notice the SUID bit set)
  9. exit



Above steps will make your adb shell run as root every time. If you do not understand how SUID bit works in Linux (android has linux kernel after all) you can look at following post : Quick introduction to SUID: What you need to know .

How to change host file in an Android device?

Goal

In this post we will see how can we edit host file in an android device.

Prerequisites and Background

You must have a rooted device!! You cannot really alter system files if your device is not rooted. Next you need android SDK. Device of course and data cable. We will be using adb tool that comes with the SDK. You can go through my earlier post on What is Android Debug Bridge (adb)?  You can also go through some helpful posts like Android Partitions and Kernel Explained  and Android Partitions Basic. If you want to root your android device you can go through that post to : How to root your Android device?


Editing the host file

  1. Navigate to the window where you adb tool is located. That would be adt-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk\platform-tools.
  2. There open the terminal and type adb devices. You should see your device listed there. If you cannot see your device listed here try steps provided here Troubleshooting steps when Eclipse ADT does not recognizing your Android device and Troubleshooting steps when Android device is detected but not recognized by Eclipse ADT.

  3. Next pull the host file using the following command

    adb pull /system/etc/hosts ./



    You should get host file in the current directory.
  4. Change the host file as per the mapping you want.

  5. Push the file back to the device using following command.

    adb push hosts /system/etc/That should push your host file back to system/etc folder. And you are done. Your host file is successfully changed.
  6.  You can cross verify your changes by logging into adb shell and viewing the host file.

  7. For above step you will have to grant adb shell su privileges. It will prompt you on the device.

  8.  Finally you can test your changes by typing test.domain.com in your android browser.  You may have to restart your phone to refresh DNS cache. It wont load because there is no server running with that URL. If you map facebook.com to this URL even facebook will not load.


Saturday, 14 June 2014

How to know IMEI number of your Andorid device?

Background

The International Mobile Station Equipment Identity or IMEI is a number, usually unique, to identify 3GPP (i.e., GSM, UMTS and LTE) and iDEN mobile phones, as well as some satellite phones. It is used to block a device from the network in case the phone is stolen. The IMEI is only used for identifying the device and has no permanent or semi-permanent relation to the subscriber. Lets see different ways to view this IMEI number for your android device.

  1. Easiest and simplest way is to dial *#06# from your phone and IMEI number will be displayed on your phone.


    Note : Mine is a dual sim android phone. Hence getting 2 IMEI numbers. Also remember IMEI has nothing to do with network or sim you are using. Instead, the subscriber is identified by transmission of an IMSI number, which is stored on a SIM card that can (in theory) be transferred to any handset.It is just to identify your device over network and if you have to slots for sim card then you will be having two IMEI numbers.
  2. View it in the setting of phone.

    1. Go to System Settings -> About Phone -> Status
    2. Here you should see a row name IMEI information .
    3. In that you will find your IMEI number.



  3. Another way to find IMEI number is to log into the google account which is used to log into google services like playstore on your device. 

    1. Go to https://www.google.com/settings/dashboard.
    2. Select the Android section (4th from top).
    3. You should see your android IMEI number listed there.


  4. Lastly you can always get to know your IMEI number as it will be mentioned on the back of your device. Open the device remove the battery and you should see your IMEI number mentioned there. I have picked up a random picture displaying this.

On Losing the Phone

When you lose your handset, you will need to launch a FIR with the police, attaching a copy of the IMEI number with it. Then give a copy of this to your service provider who can track the phone based on its unique ID number and meanwhile block the handset so that it cannot be used by anyone else. IMEI number helps to tracks the handset, even when the SIM is changed or the SIM card is not activated. Once the phone is traced, the police should be able to retrieve it. 

Important Points to Note

  • Android does not support multiple SIMs, at least from the SDK. Device manufacturers who have created multi-SIM devices are doing so on their own. So programmatically it is difficult to retrieve two IMEI numbers for a dual sim phone.
  • IMEI value survives device wipes (“Factory resets”).
  • IMEI number is device specific. It does not depend on what network provider you are using.

 

Important Links 

Connect to a database in Java

Goal

In my last post I showed how to change the default password of mysql in wamp. In this post I will show how can we connect to a database(mysql is this case) using Java. You must have mysql database installed for this.

Setup

Prior to start coding lets see what we need to complete this goal. We have mysql installed.

  1. Create a database called testDB . We will connect to this DB.
  2. Use that DB.
  3. Create a table name employee with columns as name, sex and age.
  4. Use describe command to verify the table details.
  5. Use slelect query on this newly formed table. No data is displayed.
  6. Add two enteries.
  7. Use select query again to verify data is added.




Getting Started

Lets start with writing code now. 

  1. Create a project name DBDemo.
  2. In that create a java class file named DBConnectionDemo.

In that write the following source code.

package com.opensourceforgeeks;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBConnectionDemo {
    
    public final static String query = "select * from employee";
    
    
    public static void main(String args[]) {
        
        String connectionURL = "jdbc:mysql://localhost:3306/testDB";
        Connection connection = null;
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            System.out.println("Driver not found. Provide the driver jar in the class path.");
            e.printStackTrace();
        }
        try {
            connection = DriverManager.getConnection(connectionURL, "root", "thakur");
            Statement stmnt = connection.createStatement();
            ResultSet resultSet = stmnt.executeQuery(query);
            while(resultSet.next()){
                System.out.println("Name : " + resultSet.getString(1) + " Sex : " + resultSet.getString(2) + " Age : " + resultSet.getInt(3));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        
    }
}



Expected output at this point :

Driver not found. Provide the driver jar in the class path.
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at com.opensourceforgeeks.DBConnectionDemo.main(DBConnectionDemo.java:19)
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/testDB
    at java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at com.opensourceforgeeks.DBConnectionDemo.main(DBConnectionDemo.java:25)



This is expected as we have not added the required driver jar file yet. So add the jar to your classpath.

  1. Right click the project and selectproperties.
  2. Go to java build path -> libraries
  3. Select add external library and add the mysql connector jar(download)



Now rerun the program. You should get the correct output.


Name : Aniket Sex : Male Age : 23
Name : Abhijit Sex : Male Age : 21



NOTE :  If you are using java 7 like me the there is no need to even load you driver class using Class.forName() because java7 comes with JDBC 4 and for JDBC 4 appropriate driver class will automatically be picked up from the class path. So all you have to do is add the jar in the class path.


Related Links

Changing default mysql password in WAMP server.

Background

WAMP is "Windows, Apache, MySQL, and PHP", an application server platform.
You can download it from WAMP site.
 Default password for mysql is String with no length. So on getting prompt for password simply pressing enter would log you into the mysql console as root.

Understanding the architecture

Lets understand where this password for root use is stored. We can then see how can we go modifying it. To start with open mysql console. It will ask for password simply press enter. You should see the following screen.


Next take a look at the databases that come preconfigured. For that simply execute 

mysql > show databases;

You should get some databases. The database we are interested in is mysql database. So go ahead and and execute

mysql > use mysql;

You should get message database changed. See following screen shot


If you wish to see tables in this database you can do

mysql > show tables;

You will see all the tables in this mysql database. The table we are interested in is the table user.



If you want to see what columns make up this table user and what is its data type you can execute following command.

mysql > describe user;

  You can see a lot of columns in the table. But columns that are of our interest are Host, User and Password. Host is the URL. Like you can have localhost or 127.0.0.1 etc. User is the user for which the row is. Example can be the root (This is the user for which we will be changing the password). But you can also have other users and add new users. Finally password is the password that the particular user enter when he logs into mysql console.


Now we know that the default password is a String with no length i.e "". Lets verify this
 Run following command - 

 mysql > select host,user,password from user where user='root';

This should show you that the password is a blank value.

Changing the password

With the above background lets change our password. Execute the following command

mysql > update user set password=PASSWORD('newpassword') where user='root';

(Replace newpassword with your password) .

Note : Password will be stored as encrypted String.

Then you can verify that the tables are indeed changes using previous query

 mysql > select host,user,password from user where user='root';


 Now you will have to flush privileges.

mysql > flush privileges;


You have changed your password successfully. Next time you login to mysql console you will have to enter this password. To exit mysql console simple use exit command.

mysql > exit


Related Links

Wednesday, 11 June 2014

MCQ #15

Question :

Consider the following  code : 

class Super { static String ID = "QBANK"; }
class Sub extends Super{
static { System.out.print("In Sub"); }
}
public class Test{
public static void main(String[] args){
System.out.println(Sub.ID);
}
}

What  will  be the output  when  class Test  is run ?

A. I t  will  print  In Sub and QBANK.
B. I t  will  print  QBANK.
C. Depends on  the implementation  of  JVM.
D. It  will  not  even  compile.
E. None of  the above.

Answer

Answer is option B.

Explanation 

It would look like the program would print  "In sub" followed by QBANK and the option would be A but it is not. 

Since ID is inherited from the Super class it is really the Super class that is initialized and not the Sub class. So that static method in Sub class will not get printed. 

A class is initialized only when it's content (variables/methods) which are not inherited gets referenced. Not otherwise.

From JLS 12.4.1:
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.

Tuesday, 10 June 2014

Change Tomcat Server's timeout in Eclipse

I got the following error on Eclipse while starting Apache Tomcat



So in this post I will show how can we increase the server timeout for Tomcat.

  • Go to the server view

  • Double click the Server. Configuration window would open. On the right hand side you could see Timeouts dropdown tab. You can go in that tab. It will have time limit for start and stop. Change it as per your need.

Default start time limit is 45 second where as stop limit is 15 secs.

Spring MVC Hello Wold Example

Goal

In this post I will demonstrate how to create a simple Spring MVC project. This will be an end to end demo. I will conclude the post by showing the working demo. I am going to use Apache Ivy for dependency management. For installing and using Apache Ivy you can go though my earlier post-
Installing and using Apache Ivy as dependency manager.

Getting Started

So lets get started.

  • Open up your eclipse. Note you need the EE version of eclipse as we will be needing server to run our project on. 
  • In Eclipse create a new project of type "Dynamic Web Project" (Screenshot below)
  • Next give your project a name. In my case I am naming my project GreeterProject.
  •  Ensure that you have selected Apache Tomcat 7.0 as your target runtime. If not select new runtime them select Tomcat 7. Next either provide the installation directory where you have installed the tomcat or if not eclipse will do that for you(Screnshots below)

  •  Once you have done this your project structure would look like -
  • Before we start coding lets add ivy dependency to the project. We will look into what dependency we need and what needs to go into ivy file but for now lets create one. Right click your project folder and select add -> Others -> Ivy file. It should ask you what container ivy file is for. Select out GreeterProject from the list. You can give organization and module name as per your wish.
  •  Check your WebContent/WEB-INF folder. You should have a web.xml file. This is the file where we provide all configurations needed for our project. If it is not present then create one. Its simple. Right click that folder-> new -> xml file -> name it web.xml.
  • Add the following content in the file

    <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">
    
      <display-name>Spring Web MVC Demo Application</display-name>
      
      
      <servlet>
          <servlet-name>mvc-dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
      </servlet>
    
      <servlet-mapping>
         <servlet-name>mvc-dispatcher</servlet-name>
            <url-pattern>*.htm</url-pattern>
      </servlet-mapping>
      
    
    </web-app>
    
  • Lets understand what above configuration says. It defines a default servlet called mvc-dispatcher and it define a mapping. Tha mapping is also very simple to understand. It maps a servlet to a url-pattern. In above case it means on our server any url that comes if has the pattern *.htm then forward it to mvc-dispacher servlet to handle. If you see the class of the servlet we have mentioned it is org.springframework.web.servlet.DispatcherServlet. That is it is a dispacher servlet provided by Spring MVC framework. As the name suggests its work is to dispatch the requests to various modules called controllers. Don't worry we will come to it :). But for now get this that the mention servlet will simply handler the urls with pattern *.htm and will redirect it to different controllers for further processing. So where is this mapping of controller and url provided ?
  • It is provided in a spring configuration file. By default Spring MVC framework will search for a file name "dispacherServlet name" + "-servlet.xml" which in our case will turn out to be mvc-dispatcher-servlet.xml. So go ahead create this file under WEB-INF and put the following content in it.

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        
    
        <bean id="viewResolver"
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix">
                <value>/pages/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>
    
        <bean id="urlMapping"
            class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/welcome.htm">testController</prop>
                </props>
            </property>
        </bean>
    
        <bean id="testController" class="TestController">
        </bean>
    </beans>
    

    This is just one way spring file are configured i.e if your servlet name is myservlet Spring framework will look for file named myservlet-servlet.xml. Other way is to manually provide the configuration files in the servlet tag itself in web.xml file

      <servlet>
          <servlet-name>mvc-dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
            <init-params>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/mservletconfig.xml</param-value>
            </init-params>
      </servlet>
    


    NOTE :  This may not be a good idea if you have multiple entries into you spring application i.e not just DispacherServlet , you may be supporting SOAP based web services. Providing spring initialization files in each servlet declaration as init-params is not necessary. In that case you can do

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mservletconfig.xml</param-value>
    </context-param>
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    <listener>
    


    This will essentially listen for all application contexts that are loaded and will load the common spring files for each entry point (multiple servlets for eg.).
  • Lets try to understand the content of this file. Lets start from the bottom. We have a controller name testController and it's class is TestController. But wait .... where is this TestController class? That's right you need to create one. But just in a while. Lets understand all the content in the spring config file. Next what you see is a bean with mapping. Class corresponds to functionality that is provided by Spring MVC itself. So nothing to worry about. In mapping you can see the key and the value between the tag. What does it say ?

    It simply says if the incoming URL has /welcome.htm at the end forward its request to testController. So to sum the this up first the request comes to the server(actually tomcats container name Catalina). As mentioned in web.xml if the url is of patter *.htm request will be forwarded to mvc-dispatcher servlet. This servlet will forward the request to testController if it has /welcome.htm in the url end.

    Lastly what you see is a bean called resolver. Class is again of that provided by Spring. You see something called prefix and suffix tags. What a controller returns is a ModelAndView object. It has a name. What view resolver does is that it bundles this name in between prefix and suffix and creates a path. This path points to a JSP file which is then sent to the client(browser).

     
  • Enough of the theory lets get started. First create a class called TestController in the src folder and add the following content in the file.

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.AbstractController;
    
    
    public class TestController extends AbstractController {
        
        @Override
        protected ModelAndView handleRequestInternal(HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            System.out.println("Entered TestController");
            ModelAndView model = new ModelAndView("greetings");
            return model;
        }
    
    }
    
     
    
  •  So our class extends a class AbstractController. And in this we override a method called handleRequestInternal() which handles the request. Here we are creating an ModelViewObject with name "greeting" and returning it. Now read the previous to previous point again. Our View resolver will now be looking for a file called /pages/greetings.jsp to send to the client/browser.
  • I wrote the class but I am seeing a lot of red lines. None of the classes are getting resolved. Why would it be? We are talking about Spring MVC for some time now but where is the framework/jar? Thats right its time to use Ivy. Open the ivy file and add following content -

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!--
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at
    
         http://www.apache.org/licenses/LICENSE-2.0
    
       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.    
    -->
    <ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
        <info
            organisation="OpenSourceForGeeks"
            module="Greeter"
            status="integration">
        </info>
        <dependencies>
        
            <dependency org="org.springframework" name="spring-webmvc"
                rev="4.0.4.RELEASE">
            </dependency>
            
        </dependencies>
    </ivy-module>
    
     
    
  • After this right click Ivy file and select add ivy library. This will automatically download Spring MVC and add it to your classpath. After ivy resolution is complete you will see all errors gone.
  • Next lets complete our directory structure. Create a folder called pages (remember the prefix ? )under WebContent folder and add greetings.jsp file in it with following content.

    <%@ 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>Spring Demo Example</title>
    </head>
    <body>
    <h1><b><i>Hello World!! Welcome to Spring MVC Demo!!</i></b></h1>
    </body>
    </html>
    
  •  Just to make sure that we are in sync till now lets check that our directory structures map.



  • Looks like we completed all requirement for running our demo. Go ahead fire up the server. Right click the project-> Run as - > Run on server -> Select our Apache tomcat 7 that we configured earlier.

     
  • Opss!!!! What on earth is this exception

    java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet I remember I added the Spring in ivy and it did not complain on compilation. So why sudden exception on running. Well that actually should give you the hint. Our library is available at compile time but not at runtime. It's really very simple to resolve this. You need to add ivy to deployment assembly for runtime, I have documented steps to do this with detailed screenshots in s separate post. You can go through it(Click this link). That should resolve that error.
  • Lets run it again. Works fine?? You should not see any errors and see something like server startup

  •   We are all set now lets test our project. Open the URL "http://localhost:8080/GreeterProject/welcome.htm" in your web browser. You should see
  • If you are getting
    java.lang.LinkageError: javax.servlet.jsp.JspApplicationContext.getExpressionFactory
    error do the following changes in the ivy -

            <dependency org="org.springframework" name="spring-webmvc"
                rev="4.0.4.RELEASE">
                <exclude org="javax.servlet" name="javax.servlet-api" />
                <exclude org="javax.servlet.jsp" name="jsp-api" />
                <exclude org="javax.el" name="javax.el-api" />
            </dependency>
    


    and it should work. You can also see my answer for this error on Stack Overflow for more information.

Related Links

t> UA-39527780-1 back to top