Raible's Wiki
Raible Designs AppFuseHomepage- Korean - Chinese - Italian - Japanese QuickStart Guide User Guide Tutorials Other ApplicationsStruts ResumeSecurity Example Struts Menu
Set your name in
UserPreferences
Referenced by
JSPWiki v2.2.33
Hide Menu |
This is version 42.
It is not the current version, and thus it cannot be edited. Part II: Create Weblog UI - A HowTo for creating a UI (in Struts) for managing the DAOs created in the Hibernate Relationships tutorial. I've eliminated creating managers in this tutorial for a couple reasons: 1) to reduce the amount of code and 2) to show you that you don't have to create them. About this TutorialIn this section, you'll create a UI that has the following features.
Table of Contents
Modify userForm.jsp to allow creating/editing a weblog [#1]In order for the Struts version of AppFuse to allow editing of a Weblog's attributes from the User object, you need to modify User.java to support indexed properties. You can do this by adding indexedProperties="true" to the @struts.form tag in User.java.
A weblog record has 3 fields: weblogId, blogTitle and dateCreated. The blogTitle is the only field that users should be able to edit. The rest of them can be set programmatically. Open web/pages/userForm.jsp and add the following code to the bottom of the form (between </table> and </form>. <fieldset style="position: absolute; top: 190px; left: 520px"> <legend style="font-weight: bold">Weblogs</legend> <c:forEach var="blog" items="${userForm.weblogs}" varStatus="index"> <input type="hidden" name="weblogs[<c:out value='${index.index}'/>].weblogId" value="<c:out value='${blog.weblogId}'/>"/> <input type="hidden" name="weblogs[<c:out value='${index.index}'/>].dateCreated" value="<fmt:formatDate value='${blog.dateCreated}' pattern="MM/dd/yyyy"/>"/> <input type="text" name="weblogs[<c:out value='${index.index}'/>].blogTitle" size="40" value="<c:out value='${blog.blogTitle}'/>"/><br/> </c:forEach> </fieldset> Run ant clean deploy, go to http://localhost:8080/appfuse/editProfile.html and login as "tomcat/tomcat". You should see a screenshot like the one below. If you try to save at this point, you'll probably get the following error:
The process did not complete. Details should follow.
IllegalArgumentException occurred calling getter of org.appfuse.model.Weblog.weblogId object is not an instance of declaring class This happens because the "weblogs" property of User is populated with a bunch of WeblogForm objects, instead of Weblog objects. Modify the UserAction to support editing a user's weblogs [#2]To fix saving a User, add convertLists(user) to the save() method of UserAction.java (in src/web/**/webapp/action):
In addition, you can add convertLists(user) to UserAction.edit():
This will allow you to get rid of the <fmt:formatDate> tag around the dateCreated property. <input type="hidden" name="weblogs[<c:out value='${index.index}'/>].dateCreated" value="<c:out value='${blog.dateCreated}'/>"/> Run ant deploy, wait for Tomcat to reload your application, and then try saving the User Profile again. This time it should succeed - and you can also change the blog title if you so choose. Create a WeblogAction to handle CRUD-ing Weblogs [#3]In order to edit a Weblog object, and it's children (Users and Entries), you need to create a WeblogAction.java class. Before you do that, you'll need to add a couple constants to src/dao/**/Constants.java:
Then download WeblogAction.java and put it in your src/web/**/webapp/action directory. This class already has the convertLists(Object) methods that you added to UserAction.java. Create JSPs to display a Weblog's information [#4]Add the following i18n keys to web/WEB-INF/classes/ApplicationResources.properties. You'll need these for the master/detail screen when editing weblogs. # -- weblog form -- weblogForm.weblogId=Weblog Id weblogForm.blogTitle=Blog Title weblogForm.dateCreated=Date Created weblogForm.entries=Entries weblogForm.users=Users weblog.added=Weblog has been added successfully. weblog.updated=Weblog has been updated successfully. weblog.deleted=Weblog has been deleted successfully. # -- weblog list page -- weblogList.title=Weblog List weblogList.heading=Weblogs # -- weblog detail page -- weblogDetail.title=Weblog Detail weblogDetail.heading=Weblog Information Create weblogList.jsp and weblogForm.jsp files in web/pages. Add a "WeblogMenu" to web/WEB-INF/menu-config.xml: <Menu name="WeblogMenu" title="weblogList.title" page="/weblogs.html"/> Add this menu to web/pages/menu.jsp: ... <menu:displayMenu name="WeblogMenu"/> </menu:useMenuDisplayer> There is an issue with Struts where the client-side validation blows up if you have <html:javascript> tags in your page and no validation rules defined. To prevent this from happening, add at least validation rule to Weblog.java. For example, that blogTitle is a required field.
At this point, you should be able to run ant deploy reload and navigate to the "Weblog List" (from the menu). You should also be able to perform CRUD on a weblog object. NOTE: If you get a "invalid LOC header (bad signature)" error, you'll need to stop/start Tomcat to get rid of it. To prevent it from happening in the future, you'll need to patch build.xml and metadata/web/web-settings.xml (APF-123).One issue you might run into when adding a new Weblog is that a created date is not set. To fix this, add the following in WeblogAction.java (in the save() method):
Add the ability to edit users from the Weblog Detail Screen [#5]In order to view and edit the Users associated with a Weblog, you need to add some code to weblogForm.jsp that will allow you to do this. After the "dateCreated" row, add the following:
The WeblogForm is request-scoped, so that's why you have to put all the attributes of user as hidden fields in the page. Other options include making the form session-scoped, as well as re-fetching the object in your Action before saving it. All of these approaches have issues:
The request-scoped method is used in this example because it's one of the easiest to understand. This particular "editing users in a weblog form" probably wouldn't be used in the real world (rather you'd have a <select multiple="multiple"%gt;). However, it does show you how to edit a many-to-many on both ends. In UserAction.java, there is logic to grab the usersRoles, fetch the Role objects from the database, and set them on the User object. You need to replicate this functionality in WeblogAction. Add the following just after the convertLists() call in WeblogAction.save():
Run ant deploy db-load and navigate to the Weblog with an id of 2. This weblog should have one user assigned to it - the mraible user. To add an additional user, run the following against your database: insert into weblog_user values ('tomcat', 2); If you're using < AppFuse 1.9, You may notice that the disabled fields are highlighted with a border when you click on those fields - even though they aren't editable. To fix this, apply this patch. Also, note the use of class="tallCell on the <th> that holds the Users: caption. This is used to put the caption at the top of the cell. After inserting the tomcat user and refreshing the page - your screen should resemble the image below. You should be able to modify the first and last name of the listed users without any issues.
To:
Add the ability to edit entries from the Weblog Detail Screen [#6]To edit a Weblog's entries on the same weblog form, you need to add some more code, just after the Users row.
Run ant deploy db-load and view the same weblog again. You should see a screen like the one below: If you try to clicking the "Save" button, you'll get a nice and descriptive javax.servlet.ServletException: BeanUtils.populate stack trace. This is caused by the fact that the struts_form.xdt (prior to AppFuse 1.9) did not account for plurals that ended in "ies". To fix this, replace metadata/templates/struts_form.xdt with the latest one from CVS (right-click, save as). Run and clean deploy and try clicking the Save button again. This time you might get the following lovely error:
The process did not complete. Details should follow.
Could not convert java.lang.String to java.sql.Timestamp I'll admit, I struggled with this issue for hours and I still don't have a good solution. From my hours of trial-and-error, the only conclusion I can come up with is that Struts (and Commons BeanUtils in particular) can't handle java.util.Date and java.sql.Timestamp together very well. If you know of a solution that'll allow displaying and saving a date and timestamp on the same form, please comment on APF-176. The problem is basically that I can't get the DateConverter to recognize Date as a java.util.Date - for some reason it thinks it's a Timestamp in the following logic:
For the purpose of this tutorial, you'll need to replace your src/service/org/appfuse/util/DateConverter.java with the latest one from CVS.
Add the ability to delete an entry
Attachments:
|