You are on page 1of 5

Spring Multiple Form Controller

Introduction As you may already guessed, the goal of this feature is to provide a Spring controller capable of handling many WEB forms with different actions within the same WEB page or view. The main problem with such feature is how to handle different form beans with different scopes (re uest, session, ...! and, thus, handling many forms validation within the same controller. Objectives "# To render multiple forms within the same WEB page when it$s firstly re uested. %# After a specific form submission, to bind the data to the appropriate form bean (a &'('! and then to validate it. )# To re#render the multi#forms view in case of validation error. *+ Ta,e into account the previous validation errors of all forms. -# .f the validation is successful, redirect to the appropriate success view. Implementation The main idea of this implementation is to have a controller that maintains a map of form bean configurations. The following class represents such bean config. /

The 0ormBean1onfig class attributes accessors (getters 2 setters! are omitted form more simplicity. .Scope is a simple interface that contains different strings constants denoting the different form bean scopes.

khaled.yousfi@gmail.com

The controller needs all the form bean configurations in order to handle appropriately a submitted form or simply its multi#forms view. This multi#form controller implementation maintains a map of ,ey#value. The ,eys are the action names of the forms whereas the values are instances of the form bean configurations (singletons!. &lease ta,e a loo, at the smfc#servlet.3ml from the demo application /
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/X !"chema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans # http://www.springframework.org/schema/beans/spring-beans-2.$.%s&"> <bean class="org.springframework.web.ser'(et.'iew.)nterna(*eso+rce,iew*eso('er"> <property name="prefi%" value="/-./-)0F/1sp/" /> <property name="s+ffi%" value=".1sp" /> </bean> <bean id="message"o+rce"# class="org.springframework.conte%t.s+pport.*eso+rce/+n&(e essage"o+rce"> <property name="basenames"> <list> <value>messages</value> <value>errors</value> </list> </property> </bean> <!-- C !"# LL$#% --> <bean id="we(come2ontro((er"# class="com.3k.spring.smfc.web.-e(come2ontro((er" /> <bean id="+r(Fi(ename,iew2ontro((er"# class="org.springframework.web.ser'(et.m'c.Ur(Fi(ename,iew2ontro((er"/> <bean id="m3 +(tiform2ontro((er"# class="com.3k.spring.smfc.web. 3 +(tiform2ontro((er"> <property name="form,iew" value="forms"/> <property name="actions"> <map> <entry &ey="/(ogin4ction.htm" value-re'="(oginForm2onfig"/> <entry &ey="/search4ction.htm" value-re'="searchForm2onfig"/> <entry &ey="/post essage4ction.htm" valuere'="post essageForm2onfig"/> <entry &ey="/a&&4+thor4ction.htm" valuere'="a&&4+thorForm2onfig"/> </map>

khaled.yousfi@gmail.com

</property> </bean> <!-- ( #)% C !(*+,#-"* !% --> <bean id="(oginForm2onfig"# class="org.springframework.web.ser'(et.m'c.Form/ean2onfig"> <property name="scope" value="session"/> <property name="s+ccess,iew" value="re&irect:(ogin4ction"+ccess,iew.htm"/ > <property name="comman&2(ass" value="com.3k.spring.smfc.&omain.!ogin"/> <property name="comman&0ame" value="(ogin"/> <property name="'a(i&ator" re'="(oginForm,a(i&ator"/> </bean> <bean id="searchForm2onfig"# class="org.springframework.web.ser'(et.m'c.Form/ean2onfig"> <property name="scope" value="re5+est"/> <property name="s+ccess,iew"# value="re&irect:search4ction"+ccess,iew.htm"/> <property name="comman&2(ass" value="com.3k.spring.smfc.&omain."earch"/> <property name="comman&0ame" value="search"/> <property name="'a(i&ator" re'="searchForm,a(i&ator"/> </bean> <bean id="post essageForm2onfig"# class="org.springframework.web.ser'(et.m'c.Form/ean2onfig"> <property name="scope" value="session"/> <property name="s+ccess,iew"# value="re&irect:post essage4ction"+ccess,iew.htm"/> <property name="comman&2(ass" value="com.3k.spring.smfc.&omain. essage"/> <property name="comman&0ame" value="message"/> <property name="'a(i&ator" re'="post essageForm,a(i&ator"/> </bean> <bean id="a&&4+thorForm2onfig"# class="org.springframework.web.ser'(et.m'c.Form/ean2onfig"> <property name="scope" value="session"/> <property name="s+ccess,iew"# value="re&irect:a&&4+thor4ction"+ccess,iew.htm"/> <property name="comman&2(ass" value="com.3k.spring.smfc.&omain.4+thor"/> <property name="comman&0ame" value="a+thor"/> <property name="'a(i&ator" re'="a&&4+thorForm,a(i&ator"/> </bean> <!-- ,#L )-..*!+% --> <bean class="org.springframework.web.ser'(et.han&(er."imp(eUr(6an&(er apping"> <property name="mappings"> <props> <prop &ey="/we(come.htm">/elcomeController</prop> <prop &ey="/forms.htm">my)ulti'ormController</prop> <prop &ey="/(ogin4ction.htm">my)ulti'ormController</prop> <prop &ey="/search4ction.htm">my)ulti'ormController</prop> <prop &ey="/a&&4+thor4ction.htm">my)ulti'ormController</ prop> <prop &ey="/post essage4ction.htm">my)ulti'ormController</prop> <prop

khaled.yousfi@gmail.com

&ey="/(ogin4ction"+ccess,iew.htm">url(ilename0ie/Controller</prop> <prop &ey="/search4ction"+ccess,iew.htm">url(ilename0ie/Controller</prop> <prop &ey="/post essage4ction"+ccess,iew.htm">url(ilename0ie/Controller</prop> <prop &ey="/a&&4+thor4ction"+ccess,iew.htm">url(ilename0ie/Controller</prop> </props> </property> </bean> </beans>

o! the controller !orks " When a multi#forms view is re uested, the controller creates binders (validation! and saves the errors holder to the appropriate scope. 4ere is the save#rrors method /
protected final void save$rrors1(orm2eanCon'ig 'orm2eanCon'ig3 4ttp%ervlet#e5uest re5uest3 2ind$xception errors6 7 if 1'orm2eanCon'ig != null6 7 if1logger8is9ebug$nabled1667 logger8debug1:2ean Con'ig is not null8 %aving errors ob;ect888:6< = if 1'orm2eanCon'ig8is#e5uest(orm166 7 re5uest8set-ttribute1/)078.**9*"8"29:. > 'orm2eanCon'ig8getCommand!ame163 errors6< return< = if 1'orm2eanCon'ig8is%ession(orm166 7 re5uest8get%ession1false68set-ttribute1/)078.**9*"8"29:. > 'orm2eanCon'ig8getCommand!ame163 errors6< return< = throw new *llegal%tate$xception1:,n&no/n 'orm bean con'ig scope : :>'orm2eanCon'ig8get%cope166<//!ot*mplemented$xception ?? =else7 if1logger8is9ebug$nabled1667 logger8debug1:2ean Con'ig is null8 !o saving o' the errors ob;ect8:6< = = =

When submitting a form, the controller should validate the submitted form data and save the eventual errors to the appropriate scope. .f there is any error, this controller restores all the previous validation errors and re#render the input view page.

khaled.yousfi@gmail.com

4ere is the restore#rrors method /


/?? ? #eturns the validation errors o' the 'orm bean given its con'iguration bean instance8 ? @param 'orm2eanCon'ig ? @param re5uest ? @return ?/ private 2ind$xception restore$rrors1(orm2eanCon'ig 'orm2eanCon'ig3 4ttp%ervlet#e5uest re5uest6 7 if1'orm2eanCon'ig8is#e5uest(orm1667 return restore$rrors(rom#e5uest1'orm2eanCon'ig8getCommand!ame163 re5uest6< = if1'orm2eanCon'ig8is%ession(orm1667 return restore$rrors(rom%ession1'orm2eanCon'ig8getCommand!ame163 re5uest6< = throw new *llegal%tate$xception1:,n&no/n bean con'ig scope : :>'orm2eanCon'ig8get%cope166<//!ot*mplemented$xception ?? = private 2ind$xception restore$rrors(rom%ession1%tring command!ame3 4ttp%ervlet#e5uest re5uest6 7 return 12ind$xception6re5uest8get%ession1false68get-ttribute1/)078.**9*"8"29:.>command! ame6< = private 2ind$xception restore$rrors(rom#e5uest1%tring command!ame3 4ttp%ervlet#e5uest re5uest6 7 return 12ind$xception6re5uest8get-ttribute1/)078.**9*"8"29:.>command!ame6< =

Conclusion Even though it$s not yet validated and integrated, this feature demonstrates how Spring framewor, is easy to handle and to use. As a future feature $o%, we can imagine a spring tool that automatically generates a fully functional 1567 web application given a database table. The multi#forms controller could help us to create a $multi criteria search form$ on the top of a view with a selectable items list on the view main part.

khaled.yousfi@gmail.com

You might also like