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


Multiple session or multi-window problem and solution where multiple class uses a same form extended from SimpleFormController of Spring MVC

May 8, 2008

Problem:
Lets think of a scenario, we are running a hospital management system. We need to search for patient’s record, doctor’s record, medicine stock record and many other things. Where searching criteria are completely different to each other. In order to implement the OO pattern, we develop a common search class and different command class for different type of search. Following figure illustrates the scenario:

If have created separate bean for Medicine, Doctor and Patient with Search class and define the separate command class for medicine, doctor and Patient. Works fine if you run all these separately. But Open a search page for Doctor then open a search page for Medicine in new window or tab and now press search button for doctor. What happens? You got the search result for Medicine though you suppose to get search result for Doctor.

Observation:
This is one of the most interesting problem of session related task in Spring MVC. Lets go into tail. SimpleFormController of Spring MVC extended from AbstractFromController of spring MVC this contains a method called getFormSessionAttributeName(). The spring framework source code 2.5 returns a string from this method in following way.

protected String getFormSessionAttributeName() {
return getClass().getName() + ".FORM." + getCommandName();
}

This is called 2 times, one while showing the form and one while submitting the form. If your class name is GeneralSearch and package name is net.project.web.search then this method will return the attribute name as net.project.web.search.GeneralSearch.FORM.command. The form kept in session by this name for both searching by different command class of Doctor and Medicine because you have set setSessionForm=true by. Now how do you expect to distinguish both form while submitting it in onSubmit() method? It always replace the old command class by the newest command class thats why in method onSubmit(), out preferred command object is not retrieved accurately.

Solution:
All that we need to do in this case is to make sure the form session attribute name is different for two different command class in our whole search system. You can pass a hidden value
into into your .jsp or .ftl and add it with form session attribute name to make a different session name for each search. You can override the method getFormSessionAttributeName and add the value with the attribute name that is different for each form like following

protected String getFormSessionAttributeName( HttpServletRequest request) {
String sessionId = ServletRequestUtils.getStringParameter( request, "sessionId", null);
if (sessionId!=null) {
return (super.getFormSessionAttributeName(request) + "." +sessionId);
}
return super.getFormSessionAttributeName();
}

You can pass a specific session id as the hidden variable and retrieve it by httpServletRequest and add it with the session attribute name while showing and submitting the form. That will help you to enable to work with multiple session and multi window.

By: Md. Shahjalal


Follow

Get every new post delivered to your Inbox.