Command Class with MultiActionController

June 11, 2009 at 4:54 pm | Posted in Spring | 4 Comments

After writing a post on different types of controllers spring framework provides,  i felt the need of writing a short description of how one can use command class Object while working with MultiActionController. Now got a chance to write few additions in my previous article Why spring provide too many types of controllers As you can find the detailed descriptions of all types of controllers from internet or many books, here is a little description of such use.

Its better to read this article after when u have read atleast a part of my previous article on spring controllers that gives a detailed description of usage of MultiActionController.

To use command Class with MultiActionController, we need to configure the controller bean in the same way with all its related dependencies. the only change required is in the related function that will be used when the request is submitted to the controller.

here are the steps to be followed;

  1. create a class that must extend MultiActionController and import it from spring MVC bundle.
  2. create a bean with the same class create in step 1.
  3. create a bean with id ‘nameResolver‘ with class org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver
  4. map this with controller class. you can consult with Why spring provide too many types of controllers

these are the same steps that need to be followed whether you use command class with this controller or not.

when u create a function on which your request is going to be submitted, you are required to mention  a third parameter of  spacific type of command class for the function with HttpServletRequest and HttpServletResponse parameters respectively. like

public ModelAndView modifyClient(HttpServletRequest request, HttpServletResponse response, ClientVO clientVO) throws Exception{

// clientVO will be available with all the values that are mapped with jsp page. so it can further be used in service layer or whatever you want to do with this to get required output.

return new ModelAndView(targetPage);

}

You might noticed the difference between usage of command class in SimpleFormController and MultiActionController.

In first case we use Object class as type of command class but in this case we used the specific type of command class object. so no need to make any conversions to some other class to get its property values.


Hibernate Mapping Mystery

May 20, 2008 at 6:52 am | Posted in Hibernate | 10 Comments

Hibernate is a framework that facilitate developers in order to get the maximum benefits of ORM (object/relational mapping is the automated (and transparent) persistence of objects in a Java application to the tables in a relational database, using metadata that describes the mapping between the objects and the database).

It eliminates the use of direct SQL queries by making application independent of database. Hibernate creates a layer between the application and database so that developers can take full advantage of object orientation with normalized database relations at the back end. Instead of going into the depth of hibernate, I would prefer to dive into the core concept of hibernate mapping between objects and relations; how objects oriented hierarchy can be mapped with relational database.

Hibernate provides different types of mappings according to traditional relational databases. Means traditional foreign key associations can be mapped in different ways using hibernate.

many-to-one

Let’s start from a scenario;

You are required to develop an application that needs list of countries and their respective cities to be displayed wherever needed.

So tables for city and country with their proper associations would be your first priority.

1. A table named as ‘country’. (The possible attributes can be id (primary key), name and code).

2. A table named as ‘city’. (The possible attributes can be id (primary key), name, code and an extra attribute let’s call it country_id that will be a foreign key of country table).

And two classed to map with these tables for all required manipulations

1. A class named Country. (The possible properties can be id, name and code.

2. A class named City. (The possible properties can be id, name, code and an object of Class Country).

The hbm documents will be as follows;

city.hbm.xml

<hibernate-mapping>

1. <class name=”hibernate.example.model.City” table=”city” >

The start of hbm document tells about the class association with database table; each operation with try.hibernate.example.model.City object will affect the city table. This class will be called persistence class for city table as well.

1. <id name=”id” column=”id”>

Id mapping element will be used to specify the primary key of table.

2. <generator class=”native” />

Generator class will tell the hibernate how to define the value for primary key, native means hibernate is restricted to use underlying database id assigning strategy; like if user set primary key as auto increment (in mySQL) then even with hibernate there would be no need to set the primary key, hibernate will automatically check the underlying database strategy and follow the same thing. There are many other options available for generator class. but using native is the simplest and easiest way to let the things done by underlying database instead of hibernate.

</id>

4. <property name=”name” column=”name” />

<property name=”code” column=”code” />

Property mapping element will be used to map all those properties of City object that user want to process using object. Like only those attributes of table will be available in object that will be mapped with object properties. And if there is any property mapping for which table column does not exist then hibernate will throw an Exception. There are many attributes available for property mapping elements for different purposes. You may consult Hibernate in Action for more details.

The property tag has many other attributes as well. This is the simplest way to map properties with columns. You can use as many attributes as you like.

5. <many-to-one name=”country” column=”countryId”

class=”try.hibernate.example.model.Country” />

many-to-one relationship in city hbm is defined as

i. ‘country_id’ is a foreign key of country table (defined as column) and

ii. ‘country’ is an object of country in city Class as a representative of foreign key relationship at object level.

iii. try.hibernate.example.model.Country is the class name for Country Object.

</class>

</hibernate-mapping>

City.java

Class City implements Serilizable {

private long id; //identifier property (primary key in associated table)

private String name; //city name

private String code; //city code

private Country country; //referenced object (foreign key in associated table)

// all the properties will have getter and setters as we define properties with private access specifier.

}

Hibernate doesn’t require that persistent classes implement Serializable. However, when objects are stored in an HttpSession or passed by value using RMI, serialization is necessary. (This is very likely to happen in a Hibernate application.)

  1. Unlike the JavaBeans specification, which requires no specific constructor, Hibernate requires a constructor with no arguments for every persistent class. Hibernate instantiates persistent classes using Constructor.newInstance(), a feature of the Java reflection API. The constructor may be non-public, but it should be at least package-visible if runtime-generated proxies will be used for performance optimization.

The above city hbm document tells everything about the city object as well as about associated city table. Means that try.hibernate.example.model.City class will be mapped with city table;

a. having primary key name (as defined in underlying database - primary key should be set to auto increment)

b. name and code as properties mapped with name and code columns of associated city table.

c. many-to-one relationship with country table that is associated using foreign key relationship.

Up to this point the mappings defined is unidirectional for city object with associated country object. So while working on city objects you can get the country information to which this city belongs to.

On the other hand if you want to get all the cities of some country then you need to define bidirectional mapping; so the country hbm would look like this;

country.hbm.xml

<hibernate-mapping>

<class name=” hibernate.example.model.County” table=”country” >

<id name=”id” column=”id”>

<generator class=”native” />

</id>

<property name=”name” column=”name” />

<property name=”code” column=”code” />

<set name=”cities” inverse=”true”>

<key column=”country_id”/>

<one-to-many class=” try.hibernate.example.model.City”/>

</set>

</class>

</hibernate-mapping>

Country.java

Class Country implements Serializable{

private long id; //identifier property (primary key in associated table)

private String name; //city name

private String code; //city code

private Set cities; // collection of cities mapped with set collection

// all the properties will have getter and setters as we define properties with private access specifier.

}

  1. Hibernate requires interfaces for collection-typed attributes. You must use java.util.Set rather than HashSet, for example. At runtime, Hibernate wraps the HashSet instance with an instance of one of Hibernate’s own classes. (This special class isn’t visible to the application code). It is good practice to program to collection interfaces, rather than concrete implementations, so this restriction shouldn’t bother you.

This hbm document define collection of cities related to the country, and I think up till this level things look self explanatory,

i. key column define the column name in city table that is foreign key of associated country table.

ii. One-to-many mapping element defines that this collection will be of city objects.

iii. The most important thing is the use of inverse=”true”; it needs some explanation,

Let’s have a closer look at these two hbm documents; one thing is common in this mapping; column=”country_id” defined in many-to-one mapping of city hbm and one-to-many mapping under collection (set) mapping element.

Hibernate detects two different changes to the in-memory persistent instances. From the point of view of the database, just one value must be updated to reflect the changes: the country_id column of the city table.

Hibernate doesn’t transparently detect the fact that the two changes refer to the same database column, so at this point inverse attributes comes in to indicate that this is a bidirectional association. The inverse attribute tells Hibernate that the collection is a mirror image of the many-to-one association on the other side, Without the inverse attribute, Hibernate would try to execute two different SQL statements, both updating the same foreign key column, when we manipulate the association between the two instances. By specifying inverse=”true”, we explicitly tell Hibernate which end of the association it should synchronize with the database.

Up till now all the mapping requirements have been completed. In order to make this mapping work efficiently we need few more concepts to explore.

Cascading

You can also achieve transitive persistence using cascading in different forms, which you need in order to finish the mapping of this association. You can use cascade attribute in different forms; the simplest one is cascade=”save-update”

The cascade attribute is directional: It applies to only one end of the association.

  1. If we use cascade attribute in city’s many-to-one mapping element that would mean country object will also be saved while saving city object; so country object will become mandatory to be populated while populating city object or you will need to set nullable foreign key. Otherwise hibernate will throw an exception NULL value cant to inserted into not null column as normally foreign key column of county for city table does not allow null values to make sure that each city most belong to some country. The change in mapping will be;

<many-to-one name=”country” column=”countryId” cascade=”save-update”

class=” try.hibernate.example.model.Country ” />

So the many-to-one mapping will be replaced with this mapping element to get the benefits of cascade.

  1. If you use cascade attribute with city collection mapping in country hbm document that would mean the collection will also be saved or updated accordingly with country object. The change would be like this;

<set name=”cities” inverse=”true” cascade=”save-update”>

<key column=”country_id”/>

<one-to-many class=” try.hibernate.example.model.City”/>

</set>

Fetching Strategies

Hibernate provide different ways to fetch data from object graph. With all other strategies Lazy fetching is the most prominent.

Single point associations

For a <many-to-one> or <one-to-one> association, lazy fetching is possible only if the associated class mapping enables proxying. For the country class, we enable proxying by specifying lazy=”true”:

<class name=”try.hibernate.example.model.County” lazy=”true”>

Recall the many-to-one association from City to Country:

<many-to-one name=”country” column=”country_id”

class=” try.hibernate.example.model.Country ” />

When you retrieve a city from the database, the association property may hold an instance of a Hibernate generated subclass of country that delegates all method invocations to a different instance of Country that is fetched lazily from the database (this is the more elaborate definition of a Hibernate proxy).

As soon as you declared the lazy attribute on Country, any single-point association to Country is proxied and fetched lazily, unless that association overrides the fetching strategy by declaring the outer-join attribute. outer-join allows user to choose different fetching strategies for different associations to the same proxied class.

As

<many-to-one name=”country” column=” country_id “ outer-join=”auto/true/false”

class=” try.hibernate.example.model.Country ” />

There are three possible values for outer-join:

outer-join=”auto” The default. When the attribute isn’t specified; Hibernate fetches according to the associated object. If the associated class has proxying enabled then object will be fetched lazily otherwise object will be fetched eagerly using an outer join.

i.e. in this case if we enable lazy for Country by lazy=”true” and no outer-join attribute in many-to-one mapping then if you fetch the City object, hibernate returns a subclass of Country (created by hibernate and its hidden from application code) and when you actually fetch the Country by calling its method then Country will be fetched.

Like this

<many-to-one name=”country” column=” country_id “

class=” try.hibernate.example.model.Country ” />

outer-join=”true” Hibernate always fetches the association eagerly using an outer join, even if proxying is enabled.

i.e. in our case if we set outer-join=”true” attribute in many-to-one mapping then hibernate will eagerly fetch the country Object using an outer join no matter lazy is enabled for Country or not.

<many-to-one name=”country” column=” country_id” outer-join=”true”

class=” try.hibernate.example.model.Country” />

outer-join=”false” Hibernate never fetches the association using an outer join, even if proxying is disabled.

<many-to-one name=”country” column=” country_id” outer-join=”false”

class=” try.hibernate.example.model.Country” />

Collection

Collection mappings may declare a lazy attribute, an outer-join attribute, neither, or both (specifying both isn’t meaningful). The meaningful options are as follows:

Neither attribute specified This option is equivalent to outer-join=”false” lazy=”false”. The collection is fetched from the second-level cache or by an immediate extra SQL SELECT. This option is the default and is most useful when the second-level cache is enabled for this collection.

<set name=”cities” inverse=”true” cascade=”save-update”>

<key column=”country_id”/>

<one-to-many class=” try.hibernate.example.model.City”/>

</set>

outer-join=”true” Hibernate fetches the association eagerly using an outer join. At the time of this writing, Hibernate is able to fetch only one collection per SQL SELECT, so it isn’t possible to declare multiple collections belonging to the same persistent class with outer-join=”true”.

<set name=”cities” inverse=”true” cascade=”save-update” outer-join=”true”>

<key column=” country_id”/>

<one-to-many class=” try.hibernate.example.model.City”/>

</set>

lazy=”true” Hibernate fetches the collection lazily, when it’s first accessed.

<set name=”cities” inverse=”true” cascade=”save-update” lazy=”true”>

<key column=” country_id”/>

<one-to-many class=” try.hibernate.example.model.City”/>

</set>

The most recommended fetching strategy for collections is lazy=”true” This option is almost always used for collection mappings (it should be the default, and we recommend that you consider it as a default for all your collection mappings).

One-to-One

Let’s start from a scenario;

A company needs to record his client information; its home address and his/her company information with complete address for its processing.

In order to map this scenario three tables are required;

1. A table named address having its attributes.

2. A table named user having user specific attributes with a foreign key of address,

3. A table named company having company specific attributes with a foreign key of address.

So also we need three classes namely Address, User and Company

Class User{

private long id; //identifier property (primary key in associated table)

private Address address; //referenced object (foreign key in associated table)

// all the properties will have getter and setters as we define properties with private access specifier.

}

Class Company

private long id; //identifier property (primary key in associated table)

private Address address; //referenced object (foreign key in associated table)

// all the properties will have getter and setters as we define properties with private access specifier.

}

Class Address{

private long id; //identifier property (primary key in associated table)

private User user; //referenced object (foreign key in associated table)

private Company company; //referenced object (foreign key in associated table)

// all the properties will have getter and setters as we define properties with private access specifier.

}

In all above three classes I just omitted properties of each class except the primary key property and associated class object that will work based on foreign key.

The hbm documents are;

user.hbm.xml

<hibernate-mapping>

<class name=” try.hibernate.example.model.User” table=”user” lazy=”true”>

<id name=”id” column=”id”>

<generator class=”native” />

</id>

I just omitted the mappings of User object properties with user table columns; assuming you know this from previous discussion.

<many-to-one name=”address” outer-join=”auto” unique=”true” cascade=”all”

class=” try.hibernate.example.model.Address” />

Its old many-to-one mapping element with two changes;

1. an extra attribute unique=”true”. This attribute just change the behavior of many-to-one mapping. Without unique attribute this mapping means many addresses will be linked with same user. But our purpose is to define the relation as one-to-one. So unique attribute in this mapping make this as one-to-one association between user and address. Only one address can belong to one user.

2. Cascade=”all” here I preferred to use cascade with all. This means any operation (save/update/delete) on user object will affect the address as well. If user is being removed then its address should also be removed from the database.

</class>

</hibernate-mapping>

company.hbm.xml

<hibernate-mapping>

<class name=” try.hibernate.example.model.company” table=”company” lazy=”true”>

<id name=”id” column=”id”>

<generator class=”native” />

</id>

<many-to-one name=”address” outer-join=”auto” unique=”true” cascade=”all”

class=” try.hibernate.example.model.Address” />

Same as discussed in user.hbm document.

</class>

</hibernate-mapping>

address.hbm.xml

<hibernate-mapping>

<class name=” try.hibernate.example.model.Address” table=”address” lazy=”true”>

<id name=”id” column=”id”>

<generator class=”native” />

</id>

<one-to-one name=”user” class=”try.hibernate.example.model.User”

property-ref=”user”/>

user (of type User) is the name of property of Address that corresponds to foreign key association. But instead of mapping this property with some column of Address table used another attribute property-ref=”user” is used. This means there is no need to have a separate column in user table because more than one table is being linked to address table using one-to-one association.

<one-to-one name=”company” class=”try.hibernate.example.model.Company”

property-ref=”company”/>

same as above.

</class>

</hibernate-mapping>

Someone might get confused about the many-to-one associations in these two scenarios. But in both cases the unique attribute is the main difference that is present in address case only. unique with value true makes the relation one-to-one. so in case of City/Country association we defined a collection and in case of Address/User or Address/Company we defined single object.

All the mappings we defined in this scenario are bidirectional. There are many ways to use these mappings and also can be modified according to the requirements. Means if you don’t want to access company/user from address then there is no need to define one-to-one mapping in Address hbm document. Only the many-to-one mapping defined in user/company with unique=”true” is enough to make the relationship one-to-one. But that would be unidirectional. One can only access address from its particular object (user/company).

This is an overview of hibernate mapping and a simplest cases were defined here. In order to get the complete understanding and in depth knowledge of how hibernate works and how mappings can improve the efficiency I would recommend to study Hibernate in Action by Christian Bauer & Gavin King. It’s the best book written on hibernate.

Why spring provides too many types of controllers???

December 14, 2007 at 1:35 pm | Posted in Spring | 19 Comments

While working on MVC architecture we need different type of functionalities at minimum cost. Spring made the life easier for the java programmers with multiple types of controllers (C part of MVC that manage all the MVC structure of an application).

The books available for the beginners of spring MVC provide the best theoretical description of different types of controllers, how to use them etc… But most of the beginners get confused after reading so many types of controllers. The main question arise which controller should be used & when? Can’t there be a pattern that provides us a better solution with some mixture of these? As some time we need only page navigation, some time we require form submission etc.

The same problem I faced when I started working on spring MVC. But while working I succeeded to devise such a way of using ‘MultiActionController’ with ‘SimpleFormController’ enjoying their specific advantages while satisfying my requirements.

The purpose of this writing is just to give an idea while deciding which controller should be used for what purpose at the start of an enterprise application so that programmer can get the maximum benefits of spring MVC.

Normally SimpleFormController and MultiActionController are used to perform basic tasks in an enterprise application for related tasks to reduce the length of dispatcher-*.xml (dispatcher-servlet.xml). i would give the reader a very brief introduction of SimpleFormController & MultiActionController in order to dive into the code example.

 

 

SimpleFormController

SimpleFormController is very useful in case where you want to send lots of inputs from a form to persist, i.e., if you are required to perform a task that requires lets say 20 to 30 inputs of different types from the user and submit this form for your own business logic and persistence for latter retrieval.

In traditional jsp and servlet way

You will create a form using html having a all required inputs with a servlet mapped as its action

Take inputs from the users and submit to a servlet

Then it will use the HttpServletRequest to get all the parameters for further processing

It’s a hectic job to get all 20 or 30 fields putting them in a collection (although we can use beans in traditional jsps) or an object like BO and then perform the actual task on this data.

But in case of spring’s SimpleFormController this whole process becomes very short as you only need to map a class to the jsp and this will be available to you will the inputs in the controller. It eliminates the hectic job of using HttpServlerRequest and fetching all the parameters one by one.

 

MultiActionController

If you want to perform some related tasks like manipulation of client entity, i.e., you want to add client’s info into the system, modify existing client, or want to view all the existing clients, then MultiActionController would be the better choice as you requires almost same functionality with a little bit difference. So instead of rewriting the same code for the same functionality just showing the page (one for addClient, one for modifyClient, and one for viewClient) create a class having multiactioncontrolller functionality and display all these three pages using a single controller.

It lessens your dispatcher entries; make all the functionality starting at the same point. After some time if you need to review this processes you shouldn’t need to search out how many controllers did you developed.

 

MyMultiActionCntrl.java

public class MyMultiActionCntrl extends MultiActionController{

public ModelAndView clientIntro(HttpServletRequest request,

HttpServletResponse response) throws Exception{

// such page can be used to give some simple description for this module

return new ModeAndView(“clientIntro”);

}

public ModelAndView addClient(HttpServletRequest request,

HttpServletResponse response) throws Exception{

return new ModeAndView(“addClient”);

}

public ModelAndView modifyClient(HttpServletRequest request,

HttpServletResponse response) throws Exception{

return new ModeAndView(“modifyClient”);

}

public ModelAndView viewClient(HttpServletRequest request,

HttpServletResponse response) throws Exception{

Map map = new HasgMap();

map.put(“clients”,call a service layer function that returns the list of clients);

return new ModeAndView(“viewClient”);

}

}

 

This class may have as many functions as you require for different pages to be loaded.

This workable url whould look like this

./myMAController.htm?action=”addClient”

 

Mappings required for this class

1. <bean id=”urlMapping” class=”org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>

<property name=”mappings”>

<props>

<prop key=”/myMAController.htm”>myMACntrl</prop>

</prop>

</property>

</bean>

 

1 a. SimpleUrlHandlerMapping (above declared bean mapping) provides the way to match the requested url part with one of its entries as in our case ‘./myMAController.htm?action=”addClient”’. with this given url myMACntrl is searched. That leads us to step 2.


2. <bean id=”myMACntrl” class=”com.domain.controller.MyMultiActionCntrl”>

<property name=”methodNameResolver” ref=”nameResorlver”/>

</bean>

2 A) ./myCntrl.htm that is searched and then mapped its value to a bean having the same id as in this case myMACntrl. – That is the class that have multiple functions to be called

2 B) this bean has property named mathodNamerResolver with reference to nameResolver bean which will resolve the method name

 

3. <bean id=” nameResolver” class=”org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver”>

<property name=”paramName”> <value>action</value> </property>

</bean>

 

3 a) nameResolver bean have class org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver provided by spring that resolve the url. My method name as its name depicts with property paramName having value action (it can be any valid identifier to be used as name for method name to be resolved).

action will be the name given to the parameter that will have function name as value.

Its means using this controller you don’t need to have separate controller for each page. Only you need is to mention the function name that will load the specific page.

When we need to call one of these pages say ‘addClient’, we use the mapping as ‘./myMAContoller.htm?action=”addClient’, and the spring will map it to the bean declared with id myMACntrl using the prop attribute.

<prop name=”./myMAController.htm”>myMACntrl</prop>

Then the bean with id myMAController is searched which is the MultiActionController so the method with name ‘addClient’ will be searched that will load the page given as the returned ModelAndView of this method.

return new ModeAndView(“addClient”));

The jsp page that will be loaded

addClient.jsp page

// just ignore the jstl usage for adding new client, will be discussed shortly for the case of HOW TO REUSE A PAGE

<html>

<title>My First Spring App. </title>

<head></head>

<body>

<form id=’myClientForm’ method=’post’ action=’clientFormCntrl.htm’>

<c:set var=’client’ value=’${requestScope.referenceData.clientVO}’ scope=’page’/>

<input type=’text’ name=’name’ value=’${client.name}’/>

<input type=’text’ name=’address’ value=’${client.address}’/>

<input type=’text’ name=’category’ value=’${client.category}’/>

<input type=’submit’ value=’submit’ />

</form>

</body>

</html>

After loading this page we may use the SimpleFormController for form submission that would be better having a commandClass for true use of SFC.

 

What is commandClass ???

The class that is used to map with jsp form is called commandClass in terms of spring. While submitting a form to SimpleFormController it’s of ‘Object’ Type that is required to cast into the specific type. As in our case we use a class ClientVO as commandClass and onSubmit function of SimpleFormController as of Object type. Then it’s required to cast into its actual type that’s ClientVO.

public class ClientVO{

// property name must match with the ‘name’ attributes of each input tag to be mapped with command class

private String name=””;

private String address=””;

private String category=””;

// getters & setters

// these wrapper functions must be there in order to map all the fields of jsp

}

And the controller class will look like this

public class MyClientFormCntrl extends SimpleFormContorller{

public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,

Object command, BindException exception ) throws Exception{

ClientVO clientVO = (ClientVO)command;

// this clientVO will have all the fields input from the page you may use it for validation or business logic and may convert in to an actual BO for persistence.

One thing more, all these should be done in separate service layer so that your controller only control your application flow and all other work should be separate from this.

Upon success of you process whatever you want to do

return new ModelAndView(getSuccessView());

else // in case of any problem

return new ModelAndView (getErrorPage());

}

And the mappings required for the controller are

<bean id=”myClientSFCntrl” class=”com.domain.controller.MyClientFormCntrl”>

<property name=”commandClass” value=”com.domain.model.ClientVO”/>

<property name=”successView” value=”clientIntro”/>

</bean>

// successView can be any page with having result of last page. I reused the same intro page as successView also. In such case you may set a msg string into the session that can be displayed on the intro page like what I did

return new ModelAndView(getSuccessView(),”resultMsg”,”Client’s record has been added successfully”);

In this case I reused the page for two purposes as there is no need to create a separate page just for message display.

Up to this level we can load a page addClient using multiactioncontroller and submit form using simpleFormController.

The task of modifying an existing client can also be done without creating any other page and controller, using the same addClient page and same SimpleFormController. The modifications required are as follows;

HOW TO REUSE THE addClient page for modify client as we need to display the existing client’s record, make available for changes and then submit to save the changes.

1. Modify the modifyClient function’s body of MultiActionClass class as;

public ModelAndView modifyClient(HttpServletRequest request, HttpServletResponse response) throws Exception{

// search the required client’s record and populate the ClientVO object that is mapped with our ‘addClient’ page.

ClientVO client = service.getClientVO(searching criteria);

// say service is a client that helps searching client as populate VO object.

Map map = new HashMap();

map.put(“clientVO”,client);

return new ModeAndView(“addClient”,”referenceData”, map);

}

Using the same mapping ./myMAController.htm?action=”modifyClient” when modifyClient function is called it will load the clientVO that will be available at the jsp page

And the jstl used at addClient page do all to display the client’s info in the specified fields. That’s why we used the jstl tags to fetch the reference data having clientVO. Jstl will be discussed under the head of ‘Jstl lessens the work of programmer that jsp tags

2. The change in ClientVO is the addition of clientId as property

private String clientId=””;

to hold the id of fetched client. So that we can use the same id for updating of fetched client record otherwise underlying hibernate layer will add a new record instead of updating the previous one.

3. Add a hidden input type field in the ’addClient.jsp’ to hold the ‘id’ as

<input type=’hidden’ name=’clientId’ value=’${client.clientId}’ />

Inside the form tag.

1. You need to check the id of the clientVO whether its value is ’0’ or greater than ‘0’. If its having value equal to ‘0’ this means that new client is going to be inserted into the record otherwise clientId has the value of updating client’s id. So the existing record is going to be updated.

The best place for such type of checks can be your service class that has functionalities like fetching client’s record and populating clientVO object accordingly and also vice versa in case of insertion into the database that will require conversion from clientVO to actual business Object say Client.

Up till now using MyMultiActionCntrl that’s MultiActionController and MyClientFormCntrl that’s SimpleFormController we can add a new client’s record into our System and modify an existing client’s record.

The same way we can combine our similar tasks under MultiActionController and can use the SimpleFormController for relatively same tasks.

This is the way I devised a way to perform my tasks during job while catering the best use of spring controllers I could.

There are some other functions in SimpleFormController like onSubmit that can also be used as well. But the user should first understand their best usage scenario.

The reader may find many other alternative functions for form submission under SimpleFormController having different signatures. So the reader may use such alternatives also as for his/her convenience. In the same way MultiActionController also has another way to perform the same task like ProportyMethodNameResolver.

 

 

 

 

 

Blog at WordPress.com. | The Pool Theme.
Entries and comments feeds.

Follow

Get every new post delivered to your Inbox.