Multiple session or multi-window problem and solution where same form opened in multiple tab or window extended from SimpleFormController of Spring MVC

June 4, 2009

My previous entry about multi-window or Multiple session shows how we can maintain different session for a same form extended from SimpleFormController of Spring MVC, used by multiple class. Now what about a Form extended from SimpleFormController of Spring MVC opened in different tab or window? A new one will always replace the bean from the session after showing form on showForm() method.

showForm() method of SimpleFormController save the bean in session if setSessionForm(true) for that form just before redering the view. Session works like a HashMap. It saves the bean by a name and this name retrived by calling getFormSessionAttributeName() method. Which is simply the class name(with prefix of package name) + “.Form.command”. So the new bean always replaces the old one in session.

Problem: For example you have a Patient data entry form extended from SimpleFormController of Spring MVC. You want to update two patiend information in two different tab of your browser. You open one form fill up all data and before submit you open another form in another tab. Now the bean in the session will be replaces by this new patient’s information. Now you submit this and get back to previous tab and submit that. onSubmit() method retrive the bean from the session which is the information of the second tab. So you will get incompatible data.

Solution: Soluation is same as the previous entry. You have to override  getFormSessionAttributeName(HttpServletRequest request) method and make sure two name in the session is different. Find a unique identity for two different form. It can be patient id assigned by Hospital or clinic or database index of the patient in storage device. Choosing database index has a problem. Before you submit a new form, you do not know the index so this key is 0(=zero) for a new form.

You can generate a patient id for a new form and keep it as a request attribute and modify session attribute name by overriding getFormSessionAttributeName(HttpServletRequest request) like following code

//to set inrequest:
request.setAttribute("patientId", patientId);
//in getFormSessionAttributeName(HttpServletRequest request) method
@Override
protected String getFormSessionAttributeName(HttpServletRequest request) {
String patientId = (String)request.getAttribute("patientId");
return super.getFormSessionAttributeName()+"."+patientId;
}

So when controller calls getFormSessionAttributeName() it got different session attribute name for two different name and overwrite of bean is prohibited.

by Md. Shahjalal


Choosing a Controller for your work in Spring MVC

July 24, 2008

Spring provides good number of well structured Controller to work with Spring MVC and work flow. If you are familiar with Spring frame work, you must have work with two master piece controller SimpleFormControllerand and AbstractController. One for only view read-only request and other one includes full form handling mechanism. But this are not the end of the world. There are several Controllers that one can choose for various purpose.

AbstractWizardFormController Think about a form thats large in length. User have to scroll down dipper to fill up all the necessary fields of a form. Suppose, you are filling a long form to be a member of a job site, where there are sections like Name and Address, Job experience, Educational back grounds, Achievements e.t.c. But if all those thing bind with a single been then how about Splits this form across multiple pages? If you really want to do some thing like this, this is the controller for you :D

MultiActionController You are working with Spring MVC not in Web-Flow. But some time it needs to handle more work flow than a single one. Well though its possible to do the same task with AbstractFormController but the number of Controller will be more. For handling multiple action, this controller provides three different method:
public ModelAndView doStuff(HttpServletRequest req,
HttpServletResponse res) { … }
public ModelAndView doOtherStuff(HttpServletRequest req,
HttpServletResponse res, HttpSession session) { … }
public ModelAndView doStuff(HttpServletRequest req,
HttpServletResponse res, CommandBean command) { … }

One can choose any one of those on his requirement. But the basic problem with this Controller is it does not provide any work flow. All of this must be done by manually.

ThrowawayController The flavour of Command Pattern comes with this controller in Spring MVC. If you do not like to work with request/response stateless controller. The controller itself work as a command bean. Non-singleton. Lack of validation enforce another version of the controller named ValidatableThrowawayController.

By: Md. Shahjalal


How to use int as the key of a Map to display in FreeMarker

July 23, 2008

Map (java.util.Map) in java is used to keep a key value pair. Though map.put consider both key and value as object. But if anyone want to send a map with a key as int for view in FreeMarker (*.ftl file) it can not resolve the value of the map by ${map[key]}. Though your java code works fine with int key but FreeMarker generate error message in following way,


Exception:
Expected number, sequence, or string. messageMap evaluated instead to freemarker.template.SimpleHash on line XX,


The easiest way to get out of this error is just to make the key to string by using the command .toSting() in java code. This works fine with *.flt.

By: Md. Shahjalal


Note on ThrowawayController of Spring MVC

July 20, 2008

ThrowawayController(org.springframework.web.servlet.mvc.throwaway.ThrowawayController) of Spring MVC is an alternative for request/response-type web framework who do not wish to work with stateless singleton controllers(like SimpleFormController) with servlet request/response. For request handling this controller uses the command pattern. ThrowawayController it self works as the command bean and request handler which have state and behavior. Yes as you guess, this must be a prototype. In the configuration, you must make sure this thing by setting singletone=”false”.

<bean name="/
sampleThroughwayController" singleton="false"
class="com.project.web.SampleThroughwayController">
</bean>

The most dangerous thing about this controller is shown up by not setting this property. Neither the DispatcherServlet nor ThrowawayControllerHandlerAdapter will generate any warning for this. So, be careful to check this property before you send your code for production.

One must include ThrowawayControllerHandlerAdapter in WebApplicationContext to run this. Though by default the DispatherServlet include ThrowawayControllerHandlerAdapter but it will not work until a single ThrowawayControllerHandlerAdapter is declared implicitly in WebApplicationContext.

Not including any Servlet api with this class gives us advantage on testing. One will not need to create a MockHttpServletRequest to test this class. When you need to consider the request as a true command bean, this is the best choice for the coder in Spring MVC. There is no need to access the HttpServletRequest, HttpServletResponse classes.

ThrowawayController do not implement form work flow, so for handling validation or error it is not a good choice. But the most hassle a programmer have to face when one works with data binding. ThrowawayController do not have any customize data binding. To solve the problem Spring MVC provides ValidatableThrowawayController that supports custom PropertyEditors. oh dont forget to configure ValidatableThrowawayControllerHandlerAdapter in your WebApplicationContext as ThrowawayControllerHandlerAdapter.


HandlerAdapter of Spring Framework

June 16, 2008

One of the most exiting feature of the Spring Framework is allowing to integrate a third party framework with Spring MVC. Though most of the developer working with spring do not use because most of the application consists of only Controllers which is configured by default and no explicit configuration is required. To integrate with a system developed by other framework, this an exciting tool. HandlerAdapter (org.springframework.web.servlet.HandlerAdapter) is a system level interface that enables low coupling between different request handlers and the DispatcherServlet. The interface is like the following:


package org.springframework.web.servlet;
public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception;
    long getLastModified(HttpServletRequest request, Object handler);
}

Here is a sample of implementation of HandlerAdapter Interface named SampleFrameworkHandlerAdapter. DispatcherServlet first call support() to check the HandleAdapter support a Handler, if yes then go to handle method for model and view

public class SampleFrameworkHandlerAdapter implements HandlerAdapter {
    public boolean supports(Object handler) {
        return (handler != null) && (handler instanceof ExoticFramework);
}
    public ModelAndView handle(HttpServletRequest req, HttpServletResponse res,
        Object handler) throws Exception {
        ExoticResult result = ((ExoticFramework)handler).executeRequest(req, res);
        return adaptResult(result);
}
    private ModelAndView adaptResult(ExoticResult result) {
        ModelAndView mav = new ModelAndView();
        mav.getModel().putAll(result.getObjectsToRender());
        return mav;
    }
    public long getLastModified(HttpServletRequest req, Object handler) {
        return -1;
    }
}

You have to make the configuration in the ApplicationContext by a bean with showing full class path. DispatcherServlet looks at the ApplicationContext by default for all HandlerAdapter and find all by their type. But you must notice that when you specify a HandlerAdapter, the SimpleControllerHandlerAdapter (the default one) will not be used, you have to specify all the HandlerAdapter explicitly.

By, Md. Shahjalal
Source: Expert Spring MVC and Web Flow


Follow

Get every new post delivered to your Inbox.