Skip to main content

ExtJS 4 with Spring MVC Example

Introduction

When developing a brand new application for the company I work for, one of the first thing I implement is "authentication". Not only is this process generally a prerequisite to access many other functions but it is also very simple and covers every layer of an application, from GUI to the database.
So instead of another minimalistic "Hello World" tutorial, here is a "Login/Password" example, using 2 famous technologies : Spring MVC and ExtJS 4.  

Prerequisites

Because this tutorial is quite long, I won't go into the details of each technology I used but I will mainly focus on how ExtJS and Spring can be nicely used together. So here are the things you should know before continuing :
  • Spring framework (good knowledge)
  • Spring MVC (basic knowledge. See Spring MVC Official Documentation for details)
  • ExtJS "application architecture" (see Sencha Docs for details)
  • Eclipse IDE + Tomcat 6 (or any other web container)
You already know that ? Good, so let's move on to the tutorial.

Tutorial

Install ExtJS

"Installing" ExtJS is a big word for what we are actually doing here. Just download ExtJS 4 framework and copy it to your src/main/webapp folder (maven convention ^^) of your web application.

Configure Spring MVC

Add the required maven dependencies in your pom.xml file :
Servlet and JSP 

 javax.servlet
 servlet-api
 2.5
 provided


 javax.servlet
 jsp-api
 2.0
 provided

Spring MVC 

 org.springframework
 spring-webmvc
 3.1.2.RELEASE

Jackson library used by Spring MVC to map response objects to JSON.

 org.codehaus.jackson
 jackson-jaxrs
 1.9.7
 
In web.xml file, configure Spring MVC servlet : 

 springapp
 org.springframework.web.servlet.DispatcherServlet
 1


 springapp
 *.form


 index.jsp

Add a springapp-servlet.xml application context under WEB-INF folder : 

Spring MVC Configuration is done. There are now 2 things left to do :
  • Build ExtJS GUI
  • Implement Authentication Business logic

ExtJS Authentication GUI

We'll do a very simple screen here because my current knowledge of ExtJS is quite limited (Sorry, I started  learning it a few days ago).
First, define a file structure following the architecture guidelines explained in Sencha Documentation :

This structure is made of one file app.js, app directory and 5 subfolders :
  • controller
  • model
  • store
  • view
  • data
Here are the different files.
app.js
Ext.application({
    name: 'MyApp',
    appFolder: 'app',
    autoCreateViewport: true,
    controllers: ['AuthenticationController'],
    launch: function() {
     console.log("Launching MyApp");
    }
});
Name your application the way you want, don't forget to set 'app' as folder. 
Note the use of autoCreateViewport set to "true". This will make ExtJS automatically look for view/Viewport.js file to build it's main view. 
Finally, declare the list of dependant controllers. Here we'll only use AuthenticationController. 

view/Viewport.js
Ext.define('MyApp.view.Viewport', {
    extend: 'Ext.container.Viewport',
    requires: [
        'MyApp.view.AuthenticationForm'
    ],
    layout: 'fit',
    initComponent: function() {
        this.items = {
                xtype: 'panel',
                title: 'My App',
                height: 800,
                width: '100%',
                layout: {
                 type:'hbox',
                 align:'middle', 
                 pack:'center'},
                items:[{        
                    xtype: 'authBox'
                }]
        };
        this.callParent();
    }
});
Our viewport extends Ext.container.Viewport. It requires our authentication form (MyApp.view.AuthenticationForm) as we will include the latter to the main panel, using its xtype alias : "authBox".
this.callParent() is used to call parent Class constructor.


view/AuthenticationForm.js
Ext.define('MyApp.view.AuthenticationForm',{
 extend: 'Ext.form.Panel',
 alias: 'widget.authBox',
    title: 'Authentication Form',
    width: 250,
    bodyPadding:5,
    fieldDefaults: {
        msgTarget: 'side',
        labelWidth: 75
    },
    defaultType: 'textfield',
    url:'authenticate.form',
    items:[{
        fieldLabel: 'Login',
        name: 'login',
        allowBlank:false
    },{
        fieldLabel: 'Password',
        name: 'password'
    }],
    buttons: [{
        text: 'Submit',
        action:'auth'
    },{
        text: 'Reset'
    }]
 } 
);
 
AuthenticationForm is a "form" object (Ext.form.Panel)It is made of 2 fields and 2 buttons and points to /authenticate.form URL.
We give him his alias "widget.authBox" so that we can refer to it using 'authBox' as an xtype. 
Note the action attribute added to the submit button : 'auth'. This will enable us to add a listener to this button from the controller easily.

The GUI is done. Create a jsp that will display the form :
welcome.jsp
[...]

[...] 
The last file is index.jsp that simply forwards to welcome.jsp :
index.jsp
[...]
   
[...]

Let's now focus on ExtJS controller part.
controller/AuthenticationController.js
Ext.define('MyApp.controller.AuthenticationController', {
    extend: 'Ext.app.Controller',
    init: function() {
     this.control({
      'authBox button[action=auth]':{
       click:this.auth
      }
     });
    },
    auth: function(button) {
     console.log("Authenticating...");
     var form = button.up('form').getForm();// get the basic form
        if (form.isValid()) { // make sure the form contains valid data before submitting
            form.submit({
                success: function(form, action) {
                   Ext.Msg.alert('Success', action.result.msg);
                },
                failure: function(form, action) {
                 console.log(action.result);
                 var msg = action.result.msg;
          
                    Ext.Msg.alert('Failed', msg);
                }
            });
        } else { // display error alert if the data is invalid
            Ext.Msg.alert('Invalid Data', 'Please correct form errors.');
        }
    }
});

Use the 'action' attribute of the button to hook an custom function when user clicks on it. The syntax is close to CSS selectors : "authBox button[action=auth]". This literally means : "I'm interested in a button in authBox form whose action is named 'auth'". Well, that's exactly our button.

Then Specify the function that will be triggered when user clicks on it (click:this.auth).

The name of the function is auth(). It will just get the form using ExtJS API (see up/down functions), check that it's valid and finally submit values. 2 outcomes are possible : success or failure. In our tutorial we will just get the JSON response from Spring MVC and display a message that will be generated on the server side to show that everything works. In a real world application, we would probably handle navigation logic there.

Well that's it for ExtJS part. Not very complex after all when you know the javascript syntax. The last part is even easier and will prove again the power of Spring Framework.

Spring MVC authentication logic

First, define authentication business logic. Just create a class that will hold user login and password called Credentials.Credentials.java:
public class Credentials {
 private String login;
 private String password;
  
 public Credentials() {
  super();
 }
 public Credentials(String login, String password) {
  super();
  this.login = login;
  this.password = password;
 }
 public String getLogin() {
  return login;
 }
 public void setLogin(String login) {
  this.login = login;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
}
Then create a Service interface that will perform authentication. IAuthenticationService.java:
public interface IAuthenticationService {
 /**
  * Authenticates a user against its credentials
  * 
  * @param userCredentials
  *            login and password
  * @return user's identity
  * @throws AuthenticationException raised if authentication failed.
  */
 String authenticate(Credentials userCredentials) throws AuthenticationException;
Implement a simple version of this interface. AuthenticationMockServiceImpl.java:
@Repository(value="authenticationService")
public class AuthenticationServiceMockImpl implements IAuthenticationService {
 private final static Credentials[] creds = new Credentials[] {
   new Credentials("john", "p@zzw0rd")
 };
 
 public String authenticate(Credentials userCredentials) throws AuthenticationException {
  for(Credentials oneCredential : creds) {
   if(oneCredential.equals(userCredentials)) {
    return oneCredential.getLogin();
   }
  }
  throw new AuthenticationException("Sorry, you are not allowed to enter !");
 }

}
The only thing left to implement is the server-side controller. As we saw above:
  • ExtJS form points to /authenticate.form url, 
  • *.form is handled by Spring MVC servlet
So let's define a class that will handle /authenticate requests. This can be achieved the creation of a @Controller class.
AuthenticationController.java:
@Controller
public class AuthenticationController {
 @Autowired
 IAuthenticationService authenticationService;
 
 @RequestMapping(value="/authenticate", method=RequestMethod.POST)
    public @ResponseBody Map authenticate(Credentials cred, HttpSession ses) {
        Map response = new HashMap();
        try {
         String userName = authenticationService.authenticate(cred);
         response.put("success", true);
         response.put("msg", "Welcome " + userName);
        } catch(AuthenticationException e) {
         response.put("success", false);
         response.put("msg", e.getMessage());
        }
        return response;
    }
}
What else ? ;). Just map /authenticate to a java method of our @Controller and add a Credential object as parameter as well as HttpSession. The mapping is done automatically by Spring MVC. It will automatically create an instance of Credential and pass it to the method. That's all

The last thing to explain is controller response. You could see from the above code that we return a Map as a response body. Here again, Spring MVC will do magic and convert the Map as a JSON formatted response. How is it done ? In fact, 2 things enable that :
  • @ResponseBody will be interpreted thanks to declaration in our application context file.
  • Jackson dependency will be used by Spring MVC to make JSON conversions.
Finally, we can get server side response in our javascript controller : what we put in the response Map under "msg" key will be available in action.result.msg javascript variable.

Comments

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from javascript and jquery training in chennai . or learn thru Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry. javascript and jquery training in chennai

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hey, I enjoyed this blog. I love the way you talked about how the income ofgame-developers
    can be increased with the help of innovative skills. Today, several freelancing platforms can help developers earn good income from the comfort of their homes. Eiliana is a platform where developers can find work from global clients and boost their income.

    ReplyDelete
  4. Public cloud platforms, such as Google Public Cloud, pool resources in distributed data centers around the world that multiple companies and users can access from the internet.

    ReplyDelete

Post a Comment

Popular posts from this blog

Ext4 Apply Store Filtering

In extjs4.1: There are many way for store filtering . Some of code i give here Filtering by single field: store . filter ( 'eyeColor' , 'Brown' );   Alternatively, if filters are configured with an  id , then existing filters store may be  replaced by new filters having the same  id . Filtering by single field: store . filter ( "email" , /\.com$/ );   Using multiple filters: store . filter ([ { property : "email" , value : /\.com$/ }, { filterFn : function ( item ) { return item . get ( "age" ) > 10 ; }} ]);   Using  Ext.util.Filter  instances instead of config objects (note that we need to specify the root config option in this case): store . filter ([ Ext . create ( ' Ext.util.Filter ' , {   property : "email" , value : /\.com$/ , root : 'data' }),   Ext . create ( ' Ext.util.Filter ' , {   filterFn : function ( item ) {   return item . get ( &

ExtJS - Grid panel features

What can we do with ExtJS GridPanel? I have to develop a lot of applications in my web app and I see that grid component of ExtJS may fit in. However, I am not aware of what all things I can do with the - off the shelf available framework pieces - available plug-ins in the marketplace and - custom development through my own developers This is a typical question that we hear from the business users who wants to design an application by keeping the framework’s capability in perspective. In this article I have tried to put the list of stuff you can do with grid and hopefully that shall enable you to take advantage of the beauty of ExtJS. Pre-requisites This article assumes that you are familiar with basics of ExtJS What are the available options? In this section I will be taking you through some of the commonly seen usage of ExtJS grid panel. While covering all the capabilities of grid may not be possible, I am sure it will be helpful for the business users who want to