| At line 1 added 101 lines |
| !!! Porting the Shipping Rate SWF sample to RSF with SWF |
|
| This page documents my efforts to port the [Shipping Rate - An Ajax-enabled Spring Web Flow Sample|http://spring.ervacon.com/swf-shippingrate/] [Spring Web Flow (SWF)|SpringWebFlow] app to using the [RSF/SWF integration|RSFSpringWebFlow].\\ |
| This conversion took approximately 6 hours to complete (including documenting the process). Breakdown is as follows: approximately 1 hour to make the original app work with Maven2, 1 hour to understand the structure of the sample app, 1 hour for initial structure setup and cleanup, 1 hour to convert the JSPs to html templates with rsf:ids, 1 hour to write the RSF producers, 1 hour to for miscellaneous changes (updates to .xml, .properties).\\ |
| I would estimate that a real app conversion for an app this size would take only 3 hours since documenting the process and understanding the app would not be required. You could probably save almost another hour if the app was already using maven2.\\ |
| Feel free to send me ([Aaron Zeckoski|People]) questions or comments (or using the [mailing list|EmailLists]). |
|
| || __Sample Code (SVN):__ | [original code (with maven2 build)|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/orig] | [RSF SWF version|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/RSFSWF] |
| [Try out Shipping Rate RSF SWF on our server|http://ponder.org.uk/SWFShippingRate-RSFSWF/faces] |
|
| !! My development environment |
| * Java 1.5 |
| * Tomcat 5.5.12 |
| * Maven2 |
| * Eclipse 3.2 |
| * Windows XP ''(any OS should be fine)'' |
| __NOTE:__ Want [instructions setting up a similar development environment|ContainerSetupGuide]? |
|
| !! Getting started |
| First thing I had to do was get the SWF sample code up and running on my machine. |
| # Went to the [Spring Download page|http://www.springframework.org/download] and grabbed version 1.0.4 of SWF (this just goes over to sourceforge for the [spring-webflow-1.0.4.zip|http://downloads.sourceforge.net/springframework/spring-webflow-1.0.4.zip?modtime=1182395228&big_mirror=0]) |
| # Extracted the package and grabbed the shippingrate app (spring-webflow-1.0.4\projects\spring-webflow-samples\shippingrate) and copied it over to my desktop |
| # Imported the sample app in eclipse and added a maven2 [pom.xml file|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/orig/pom.xml] (also adjusted the [.classpath file|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/orig/.classpath] to all required jars to use M2_REPO variable). |
| #* __TIP:__ Look at the {{ivy.xml}} file to get the required dependency list and versions |
| #* __TIP:__ Don't forget to define a ''M2_REPO'' classpath variable in eclipse which points to your local maven2 repository |
| # Built the project using maven2 by running {{mvn install}} |
| # Started up tomcat and accessed the app at: ''[http://localhost:8080/SWFShippingRate-orig-1.0/]'' |
| # Checked in the [code for the original version|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/orig] to the CARET SVN |
|
| !! Creating the RSF version |
|
| ! Initial structure setup and cleanup |
|
| # Branched the [original code|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/orig] to create the [RSFSWF version|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/RSFSWF]. |
| # Adjusted the maven2 {{pom.xml}} to remove unneeded dependencies (webmvc, web, etc.) and added in the rsf-util and spring-aop dependencies. |
| #* Also changed the Spring version to 2.0.4 to make it easier for maven2 to sync and require less specified dependencies in the {{pom.xml}} |
| # Added rsf-swf and rsfutil jars to the eclipse classpath (using the M2_REPO variable) |
| # Added in an RSF standard {{content}} directory under {{/src/main/webapp}} |
| # Added in RSF standard {{content/templates}}, {{content/css}}, and {{content/images}} directories |
| # Moved *.jsp files to {{content/templates}} and renamed all files to .html |
| #* Removed the old {{jsp}} directory |
| # Updated the headers of all .html files to remove taglibs and added in standard RSF headers (also removed meta tag) |
| # Moved *.jpg to {{content/images}} and removed old {{/src/main/webapp/images}} directory |
| # Copied in the rsf logo and fixed the relative path to all images in the templates |
| #* Added logos to the front page, they were not used in the original app |
| # Moved {{/src/main/webapp/style.css}} file to {{content/css}} |
| # Added the css to the index header |
| #* Adjusted css since body font size was too small to read on high definition screens |
| # Added {{/src/main/webapp/WEB-INF/messages/messages_en.properties}} file for internationalized messages |
| # Created an {{rsf}} package in {{org.springframework.webflow.samples.shippingrate}} |
| # Added {{params}} and {{producers}} packages to the {{rsf}} package |
|
| ! Actual real conversion work |
| # Updated the {{/src/main/webapp/WEB-INF/web.xml}} file to include the RSF standard contexts and servlets |
| #* This basically means completely overwriting what is there except you can keep the {{classpath:org/springframework/webflow/samples/shippingrate/domain/services.xml}} |
| #* Here is a link to the [new web.xml file|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/RSFSWF/src/main/webapp/WEB-INF/web.xml] for easy reference |
| # Create an {{applicationContext.xml}} and {{requestContext.xml}} file in {{/src/main/webapp/WEB-INF}} |
| #* Here are links to each for easy reference: [applicationContext.xml|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/RSFSWF/src/main/webapp/WEB-INF/applicationContext.xm], [requestContext.xml|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/SWFShippingRate/RSFSWF/src/main/webapp/WEB-INF/requestContext.xm] |
| #* ''OPTIONAL:'' added an RSF config set under [SpringIDE|http://springide.org/blog/] which includes all spring files |
| # Removed the {{/src/main/webapp/WEB-INF/shippingrate-servlet.xml}} (it mostly has webmvc beans which we do not need) |
| #* Copied over the 3 flow bean definitions from within this file ({{flowExecutor}}, {{flowRegistry}}, and {{formAction}}) to the {{applicationContext.xml}} |
| #* Updated the header of the {{applicationContext}} to include the flow xmlns {{xmlns:flow="http://www.springframework.org/schema/webflow-config"}} |
| # Went through each .html template and removed the JSP code and replaced it with ''rsf:ids'' |
| #* This mostly involved the removal of non-standard html tags like {{<c:...}} and {{<spring:...}} |
| #* This also involved some moving around of tags to improve the xhtml |
| #* Also removed hidden input fields which were carrying along the flow id |
| # Created [producers|ComponentProducer] for each of the html files in the producers package |
| #* This is the ''best practice'' way to create RSF view producers |
| ## Create a class named <template>Producer which implements {{ViewComponentProducer}} |
| ## Create a {{public final static String VIEW_ID = "<template>";}} which is set to the template without .html |
| ## Make the {{getViewID}} method return the VIEW_ID variable |
| # Added all producer bean definitions to the {{requestContext.xml}} file |
| # Made the IndexProducer implement {{DefaultView}} so it is the starting page for the app |
| # Added real code to the {{IndexProducer}} to create the links to initiate the flow inside a form so we can start it using an ajax call |
| #* Added in special form tag to allow us to get the flow start url \\{{<form rsf:id="rate_flow_link_form" action="selectCustomer.html" />}} |
| #* Create the form: {{UIForm form = UIForm.make(tofill, "rate_flow_link_form");}} |
| #* Create a link to start a flow and put it in a form: {{form.viewparams = new SWFLaunchViewParams("getRate-flow");}} |
| # Added real code to the {{SelectCustomerProducer}} to connect data to the form and associate the submit with the flow |
| #* Use the RSF convention of {{SWFBindingBean}} to proxy data to the flow formObject, this points to the {{org.springframework.webflow.samples.shippingrate.domain.RateCriteria.java}} object (defined by the ''formObjectClass'' in the ''formAction'' bean) which has fields on it like {{.residential}}, \\For example: {{UISelect choices = UISelect.make(form, "customer_choices", customerOptions, customerLabels, "SWFBindingBean.residential");}} |
| #** __NOTE:__ Here we are putting data into the ''rateCriteria'' bean (defined by the ''formObjectClass'' in the ''formAction'' bean) |
| #* Use the RSF convention of {{SWFEventBean}} to continue the flow, this ties to the {{view-state}} in the flow \\({{/src/main/webapp/WEB-INF/flows/getRate-flow.xml}}) and the related ''transition'' which will have an ''on'', \\For example: {{<transition on="submit" to="selectSender">}} for __view-state id=selectCustomerType__ |
| # Added the injection for the {{RateService}} to the remaining producers |
| #* it is used in every view except {{IndexProducer}} and {{SelectCustomerProducer}} |
| # Added functional code to the remaining producers (this is basic Java and RSF code so I will not go into detail here) |
| #* This did involve injecting the {{RateCriteria}} bean into the final view so that we could send it to the {{RateService}} |
| # Added the validation messages from {{/src/main/java/org/springframework/webflow/samples/shippingrate/domain/RateCriteriaValidator.java}} to the {{/src/main/webapp/WEB-INF/messages/messages_en.properties}} |
| #* This is because RSF only allows internationalized messages |
| #* We had to add one additional validation message because of an internal Spring exception message which RSF does not have access to |
| # Committed the changed code to the [CARET SVN repository RSF samples trunk|https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/] |
|
| ! Running the sample app |
| # Built and deployed the project using maven2 by running {{mvn install cargo:deploy}} from the main directory |
| # Started up tomcat and accessed the app at: ''[http://localhost:8080/SWFShippingRate-SWFRSF-1.0/faces/]'' |
| # Tested the various flows |
|
| ! Differences in app function |
|
| ! Summary of needed changes |
| * No flows were changed and the logic for the application was not touched |
| * The "views" (JSPs) were transformed into RSF views (producers and templates) and various RSF bits were added (contexts) |
| * A few other RSFisms like internationalized messages and the web.xml had to be updated or added |