Hypertext Transfer Protocol (HTTP) is stateless: a client computer running a web browser must establish a new Transmission Control Protocol (TCP) network connection to the web server with each new HTTP GET or POST request. The web server, therefore, cannot rely on an established TCP network connection for longer than a single HTTP GET or POST operation. Session management is the technique used by the web developer to make the stateless HTTP protocol support session state. For example, once a user has been authenticated to the web server, the user's next HTTP request (GET or POST) should not cause the web server  to ask for the user's account and password again.

If not all alot of web applications want to know who is the visitor on their site. They want to expose some portions of the site with some specific set of users  and some portions for all the visitors. Web application need to identify the user by their credentials. Here we will see how this can be made possible in stateless  http enironment using spring mvc

 Server Side.

 we will start by writing a login method in Controller.

 @RequestMapping(value = { "/login" }, method = RequestMethod.POST)
    @ResponseBody
    public String login(HttpSession session,String username,String password) throws Exception {
        Member member=userService.authenticateUser(username, password);
        if(member!=null)
        {
            session.setAttribute("MEMBER", member);
        }else
        {
            throw new Exception("Invalid username or password");
        }
        return Utils.toJson("SUCCESS");
    }

 user will be passing username and password while Spring will automatically inject session attribute. we will authenticate this username and password from db. For this we will be using some service method which will in turn call some method of repository to get the Object of Member class and return it  here in the controller.

 Now this Member object will be their in the session untill the session is not destroyed due to any reason. Now what we want is that every call of method should be verified either it is a from a authenticated user or not. Some calls will be exempted from this like this login call. Of course the user who is going to login can't be pre authenticated. 

To intercept every call to handler method we will be writing handlerinterceptor.

what is HandlerInterceptor?

Sometimes we want to intercept the HTTP Request and do some processing before handing it over to the controller handler methods. That’s where Spring MVC Interceptors come handy. Just like we have Struts2 Interceptors, we can create our own interceptors in Spring by either implementing
org.springframework.web.servlet.HandlerInterceptor interface or by overriding abstract class org.springframework.web.servlet.handler.HandlerInterceptorAdapter  that provides the base implementation of this interface.

HandlerInterceptor declares three methods based on where we want to intercept the HTTP request.
we will be using this method preHandle. boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler): This method is used to intercept the request before it’s handed  over to the handler method. This method should return ‘true’ to let Spring know to process the request through another interceptor or to send it to handler  method if there are no further interceptors. If this method returns ‘false’ Spring framework assumes that request has been handled by the interceptor itself and no further processing is needed. We should use response object to send response to the client request in this case. Object handler is the chosen handler object to handle the request. This method can throw Exception also, in that case Spring MVC Exception Handling should be useful to send error page as response.

 package com.faisalbhagat.web.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;



public class SessionValidator extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
            HttpSession session = request.getSession();
        if (!(((HandlerMethod)handler).getBean() instanceof CommonController)) {
            if (session == null || session.getAttribute("MEMBER") == null) {
                throw new Exception("Invalid session please login");
            }
        }
        return true;
    }

}

so what this method prehandle is doing is obvious from the code . it gets HttpSession object from request. Then it verifies it has "MEMBER" attribute set or not remember we had set this MEMBER attribute during login. if this attribute is not null it means user has passed login method so he is a verified user if this attribute is null it means he is not verified so we must throw an Exception to tell the client "please login".  Now we dont want to have this check for every method like login and some other methods which are available to non authenticated users aswell. we will be keeping all those methods or handlers in CommonController. Outer if is saying if this handler was part of CommonController dont go for verification just return true.

Now we have to declare this SessionValidator or handlerinterceptor in ourproject-servlet.xml as follows

<mvc:interceptors>
        <bean class="com.faisalbhagat.web.interceptor.SessionValidator" />
</mvc:interceptors>


Client Side


Here is the client side code for testing
  function login()
  {
      console.log("clicked login");
      $
        .ajax({dataType : 'json',
            url : "${pageContext.request.contextPath}/login",
            data : {'username' : 'faisal' ,'password' : 'bhagat'
            },
            type : "POST",
            success : function(result) {
            alert('success'+JSON.stringify(result));
            getFeedbackList();
            },
            error : function(result){
                alert('errorsds '+JSON.stringify(result));
            }
        });
  }

  function getFeedbackList()
  {
      console.log("clicked getFeedbackList");
      $
        .ajax({dataType : 'json',
            url : "${pageContext.request.contextPath}/getFeedbackList",
            data : {'memberId' : '1'
            },
            type : "GET",
            success : function(result) {
            alert('success'+JSON.stringify(result));
            },
            error : function(result){
                alert('errorsds '+JSON.stringify(result));
            }
        });
  }
4

View comments

  1. where can i get this CommonController

    ReplyDelete
  2. A nice article here, i think that people who have grown up with the idea of using computers are showing more responsibility

    Hr Consultancy in Bangalore

    Hr Franchise in Bangalore

    ReplyDelete
  3. what will the code on Dao class of session

    ReplyDelete
  4. sir,member class was not import

    ReplyDelete
Blog Archive
About Me
About Me
Loading