At line 8 changed 1 line. |
By default, AppFuse ships with [Struts|http://struts.apache.org] as its web framework. As of 1.6, you can use [Spring|http://www.springframework.org] or [WebWork|http://opensymphony.org/webwork] as your web framework. Tapestry and JSF are planned for 1.7 and 1.8 respectively. |
By default, AppFuse ships with [Struts|http://struts.apache.org] as its web framework. As of 1.6+, you can use [Spring|http://www.springframework.org] or [WebWork|http://opensymphony.org/webwork] as your web framework. In 1.7, support was added for using [JSF|http://myfaces.apache.org] or [Tapestry|http://jakarta.apache.org/tapestry]. |
At line 10 changed 1 line. |
To install Spring MVC, navigate to {{extras/spring}}, and view the README.txt. For WebWork, see {{extras/webwork/README.txt}}. You can easily install these options in your project by running "ant install-springmvc" or "ant install-webwork". This tutorial using these two options can be found at: |
To install any of these web frameworks instead of Struts, simply navigate to the ''extras'' directory and into the directory of the framework you want to install. The README.txt file in this directory has further instructions. The tutorials for these other frameworks are listed below. |
At line 12 changed 2 lines. |
* <span style="color: green">__Spring MVC:__</span> [Creating Controllers and JSPs|SpringControllers] |
* <span style="color: blue">__WebWork:__</span> [Creating Actions and JSPs|WebWorkActions] |
* __<span style="color: green">Spring:</span>__ [Creating Spring Controllers and JSPs|SpringControllers] |
* __<span style="color: blue">WebWork:</span>__ [Creating WebWork Actions and JSPs|WebWorkActions] |
* __<span style="color: purple">JSF:</span>__ [Creating JSF Beans and JSPs|JSFBeans] |
* __<span style="color: orange">Tapestry:</span>__ [Creating Tapestry Pages and Templates|TapestryPages] |
At line 29 changed 1 line. |
Now let's generate our PersonForm object for Struts and our web tier. To do this, we need to add XDoclet tags to the Person.java Object to create our Struts ActionForm. In the JavaDoc for the Person.java file, add the following @struts.form tags (use User.java if you need an example): |
Now let's generate our PersonForm object for Struts and our web tier. To do this, we need to add XDoclet tags to the Person.java Object to create our Struts ActionForm. In the JavaDoc for the Person.java file, add the following @struts.form tag (use User.java if you need an example): |
At line 42 added 2 lines. |
Now if you run __ant gen-forms__, Ant (and XDoclet) will generate a PersonForm.java for you in build/web/gen/**/form. |
|
At line 41 changed 1 line. |
In this step, we'll generate a ''skeleton'' or our JSP for displaying information from the PersonForm. I say ''skeleton'' because it'll just be the <form> itself. It will contain table rows and Struts' <html:text> tags for each property in PersonForm.java. The tool that we use to do this was written by [Erik Hatcher|http://www.blogscene.org/erik/]. It's basically just a single class (FormTagsHandler.java) and a couple of XDoclet templates (FormKeys.xdt and StrutsForm_jsp.xdt). All these files are located in extras/viewgen. |
In this step, you'll generate a JSP page to display information from the Person object. It will contain Struts' JSP tags that render table rows for each property in Person.java. The [AppGen] tool that's used to do this is based off a StrutsGen tool - which was originally written by [Erik Hatcher|http://www.blogscene.org/erik/]. It's basically just a couple of classes and a bunch of XDoclet templates. All these files are located in extras/appgen. |
At line 45 changed 8 lines. |
* Execute __ant compile__ - this generates the PersonForm.java from the Person.java POJO. |
|
* From the command-line, navigate to "extras/viewgen" |
* Execute __ant -Dform.name=PersonForm__ to generate three files in extras/viewgen/build: |
** PersonForm.properties (labels for your form elements) |
** personForm.jsp (skeleton JSP file for viewing a single Person) |
** PersonFormList.jsp (skeleton JSP file for viewing a list of People) |
* Copy the contents of PersonForm.properties into web/WEB-INF/classes/ApplicationResources_en.properties. Here is an example of what you might add to ApplicationResources_en.properties: |
* From the command-line, navigate to "extras/appgen" |
* Execute __ant -Dobject.name=Person -Dappgen.type=pojo -Dapp.module=__ to generate a bunch of files in extras/appgen/build/gen. In fact, it'll generate all the files you need to complete this tutorial. However, let's just grab the ones you need. |
** web/WEB-INF/classes/Person.properties (labels for your form elements) |
** web/pages/personForm.jsp (JSP file for viewing a single Person) |
** web/pages/personList.jsp (JSP file for viewing a list of People) |
* Copy the contents of Person.properties into web/WEB-INF/classes/ApplicationResources.properties. These are all the keys you will need for titles/headings and form properties. Here is an example of what you should add to ApplicationResources.properties: |
At line 56 removed 1 line. |
personForm.firstName=First Name |
At line 59 added 1 line. |
personForm.firstName=First Name |
At line 61 added 12 lines. |
|
person.added=Person has been added successfully. |
person.updated=Person has been updated successfully. |
person.deleted=Person has been deleted successfully. |
|
# -- person list page -- |
personList.title=Person List |
personList.heading=Persons |
|
# -- person detail page -- |
personDetail.title=Person Detail |
personDetail.heading=Person Information |
At line 60 changed 2 lines. |
</div> |
* Copy personForm.jsp to web/pages/personForm.jsp. Copy PersonFormList.jsp to web/pages/personList.jsp. ''Notice that each of the new filename's first character is lowercase.'' |
</div> |
* Copy personForm.jsp to web/pages/personForm.jsp. Copy personList.jsp to web/pages/personList.jsp. |
At line 65 removed 2 lines. |
%%note __NOTE:__ The "viewgen" tool has been deprecated in 1.6.1 and will be removed in 1.7. The <a href="CreateDAO#appgen"> tool provides the same functionality.%% |
|
At line 72 changed 2 lines. |
* Add keys in ApplicationResources_en.properties the titles and headings in the JSPs |
In the generated JSPs, there are two keys for the title (top of the browser window) and the header (heading in the page). We now need to add these two keys (personDetail.title and personDetail.heading) to ApplicationResources_en.properties. |
* Add keys in ApplicationResources.properties the titles and headings in the JSPs |
In the generated JSPs, there are two keys for the title (top of the browser window) and the header (heading in the page). These fields are provided above with key names of personDetail.title and personDetail.heading. |
At line 75 changed 1 line. |
Open web/WEB-INF/classes/ApplicationResources_en.properties and add the following to the bottom of the file: |
''Just above, we added "personForm.*" keys to this file, so why do I use personDetail instead of personForm for the titles and headings? The best reason is because it gives a nice separation between form labels and text on the page. Another reason is because all the *Form.* give you a nice representation of all the fields in your database. |
At line 77 removed 8 lines. |
{{{ |
# -- person detail page -- |
personDetail.title=Person Detail |
personDetail.heading=Person Information |
}}} |
|
;:''Just above, we added "personForm.*" keys to this file, so why do I use personForm ''and'' personDetail? The best reason is because it gives a nice separation between form labels and text on the page. Another reason is because all the *Form.* give you a nice representation of all the fields in your database. |
|
At line 89 changed 1 line. |
To create a StrutsTestCase Test for PersonAction, start by creating a PersonActionTest.java file in the test/web/**/action directory. |
To create a StrutsTestCase Test for PersonAction, start by creating a PersonActionTest.java file in the test/web/**/action directory: |
At line 91 removed 4 lines. |
;:%%(color: blue)''As usual, copy → save as an existing ActionTest (i.e. UserActionTest). Replace [[Uu]ser with [[P]erson.''%% |
|
;:%%(color: blue)''If you do copy UserActionTest, make sure and change {{UserFormEx}} to {{PersonForm}}. [UserFormEx|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/webapp/form/UserFormEx.java.html] is an extension of UserForm that has a String[[] setter for Roles. Since the UserForm is generated, it's not very feasible to do it in the User.java object.''%% |
|
At line 217 changed 3 lines. |
new ActionMessage("person.deleted", |
personForm.getFirstName() + ' ' + |
personForm.getLastName())); |
new ActionMessage("person.deleted")); |
At line 273 changed 3 lines. |
new ActionMessage("person.added", |
personForm.getFirstName() + " " + |
personForm.getLastName())); |
new ActionMessage("person.added")); |
At line 283 changed 3 lines. |
new ActionMessage("person.updated", |
personForm.getFirstName() + " " + |
personForm.getLastName())); |
new ActionMessage("person.updated")); |
At line 299 changed 1 line. |
;:''If you are running Eclipse, you might have to "refresh" the project in order to see PersonForm. It lives in build/web/gen, which should be one of your project's source folders. This is the only way for Eclipse to see and import PersonForm, since it is generated by XDoclet and does not live in your regular source tree. You can find it at build/web/gen/org/appfuse/webapp/form/PersonForm.java.'' |
;:''If you are running Eclipse, you might have to "refresh" the project in order to see PersonForm. It lives in build/web/gen, which should be one of your project's source folders. This is the only way for Eclipse to see and import PersonForm, since it is generated by XDoclet and does not live in your regular source tree. You can find it at build/web/gen/org/appfuse/webapp/form/PersonForm.java. |
At line 295 added 2 lines. |
;:You can also configure Eclipse to auto-refresh your workspace using: Window > Preferences > General > Workspace > Refresh Automatically.'' |
|
At line 321 removed 11 lines. |
There are a few keys (ActionMessages) you need to add to ApplicationResources_en.properties to display the success messages. This file is located in ''web/WEB-INF/classes'' - open it and add the following: |
|
;:''I usually add these under the {{# -- success messages --}} comment.'' |
|
{{{person.added=Information for <strong>{0}</strong> has been added successfully. |
person.deleted=Information for <strong>{0}</strong> has been deleted successfully. |
person.updated=Information for <strong>{0}</strong> has been updated successfully. |
}}} |
|
;:''You could use generic ''added'', ''deleted'' and ''updated'' messages, whatever works for you. It's nice to have separate messages in case these need to change on a per-entity basis.'' |
|
At line 366 removed 1 line. |
Now let's clean up the generated personForm.jsp by making the "id" property a hidden field. Remove the following code block from web/pages/personForm.jsp: |
At line 368 changed 1 line. |
[{Java2HtmlPlugin |
Now let's clean up the generated personForm.jsp. Change the ''action'' of the <html:form> to be "savePerson" so validation will be turned on when saving. Also, change the ''focus'' attribute from focus="" to focus="firstName" so the cursor will be in the firstName field when the page loads (this is done with JavaScript). |
At line 370 changed 10 lines. |
<tr> |
<th> |
<appfuse:label key="personForm.id"/> |
</th> |
<td> |
<html:text property="id" styleId="id"/> |
<html:errors property="id"/> |
</td> |
</tr> |
}] |
Another thing you will need to do is comment out the following lines at the bottom of the personForm.jsp. This is because the Validator will throw an exception if a formName is specified and no validation rules exist for it. |
At line 381 changed 1 line. |
And add the following before the <table> tag: |
;:''Personally, I think this is [a bug|http://nagoya.apache.org/bugzilla/show_bug.cgi?id=27316], but the Struts Committers disagreed.'' |
At line 383 changed 1 line. |
[{Java2HtmlPlugin |
{{{<html:javascript formName="personForm" cdata="false" |
dynamicJavascript="true" staticJavascript="false"/> |
<script type="text/javascript" |
src="<html:rewrite page="/scripts/validator.jsp"/>"></script>}}} |
At line 385 removed 5 lines. |
<html:hidden property="id"/> |
}] |
|
You should change the ''action'' of the <html:form> to be "savePerson" so validation will be turned on when saving. Also, change the ''focus'' attribute from focus="" to focus="firstName" so the cursor will be in the firstName field when the page loads (this is done with JavaScript). |
|
At line 369 added 1 line. |
|
At line 398 changed 1 line. |
Finally, to make this page more user friendly, you may want to add a message for your users at the top of the form, but this can easily be done by adding text (using <fmt:message>) at the top of the personForm.jsp page. |
Finally, to make this page more user friendly, you may want to add a message for your users at the top of the form, which can easily be done by adding text (using <fmt:message>) at the top of the personForm.jsp page. |
At line 427 added 1 line. |
<verifytext description="verify success message" text="${person.updated}"/> |
At line 472 changed 2 lines. |
<verifytext description="verify success message" |
text="Information for <strong>Abbie Raible</strong> has been added successfully."/> |
<verifytext description="verify success message" text="${person.added}"/> |
At line 460 added 1 line. |
<prepareDialogResponse description="Confirm delete" dialogType="confirm" response="true"/> |
At line 462 added 1 line. |
<verifyNoDialogResponses/> |
At line 488 changed 2 lines. |
<verifytext description="verify success message" |
text="Information for <strong>Matt Canoo</strong> has been deleted successfully."/> |
<verifytext description="verify success message" text="${person.deleted}"/> |