As we can see from the previous two extreme cases, hard-coded areas occur in three places:
- Controllers
- Spring configuration files
- JSP views
To remove them, I first introduced my own binding class,
ReflectDataBinder. This custom binder parses the incoming HttpRequest
to extract parameters as parts of business beans. It instantiates those business beans and fills them up with the data carried by parameters using Spring's DataBinder. So when my framework users subclass the general form controller,
ReflectFormController and override the customized onSubmit, for example in
BambooAdminEditForm2Controller,
what they see is the beanMap instead of Command as the gievn parameter
public ModelAndView onSubmit(Map beanMap) throws ServletException {
...
}
where beanMap contains all the ready-to-use business beans carried by the HttpRequest.
As you can see in
BambooAdminEditForm2Controller, users can use the business beans to invoke APIs of next tier right away.
So the hard-coded value building area in the controllers is eliminated. On other words, I made the field level data transparent to my framework users and only expose bean level objects to users.
A further improvement will be done to provide some default behavior such as save all the business beans in the super controller class so that for most "common" controllers, there is nothing to implement in
their onSubmit.
Before I move on, I need to explaint a little bit about how I can identify which parameter belong to what business beans. The major shortage for a command object or an "ActionForm" is that it appears as a single object. That is,
Spring or Struts is able to bind http parameters to a single object by default since it only support signle command or ActionForm. In order to bind parameters on to multiple beans, I need to have a way to indicate the relation
between a bean and its fields(parameters). There are two links I need to make: 1). a link between a bean symbol(or tile name) and a field; 2). a link between the tile name and the bean info like class name an so on.
This bean symbol (tile name) represent not just a bean but also identify a piece of physical screen (I will talk about the "tile" concenpt later). The first link is achieved by using the tile name as a prefix of the
field name in html. Each field name has a format of
tileName.fieldName. This will tell my customized binder the field belong to what bean. Two classes are introduced to hold
information about the tile.
TileInfo contain tile level UI information while
FieldInfo describes the field.
A map,
BEAN_MAP, is built initially when the appication or business is loaded. It contains all the bean information. To make demo codes simpler,
I place the bean info in a static block but the bean info should really reside in xml configuration files and part of them should be automatically generated according to backend business beans.
The keys in this map are the tile names so I link the bean info to the http parameters in this way.
Next, I need to remove the hard-coded content in
springapp-servlet.xml. The reason concrete information exists in the config file is that we used
concrete command class for form controllers. So I fixed the problem by using a generaic command,
BeanMapCommand, where map is used.
And again, tile names are used as keys in the map.
At last, I need to eliminate concrete information about particular beans from JSP views. Similar to the problem in configuration area, the problem is that we use concrete views for beans. Giving each bean a concrete view is really not
a good idea (but most people keep doing it since it is simple to build but hard to maintain). Let's pick
a concrete example, in the popup screen, content of two beans appear
in the lower subframe, Bamboo and Source. They have the same type of view, form. That is, they should appear on the page as two instance of form view, just filled with different data. Under sharing view concept, I built a form view
as a tag file,
form.tag. All the business beans with a form view will share this tag. As you can see in the tag, there is no any information about a particular bean.
Show details