Thursday, July 31, 2003

I'm trying a new method for initializing a form. I still believe reset() is the best place to initialize form values, but for values that are needed in the JSP, but not for actually processing the form (contents of select boxes and other read only info), I think the Action is the best place to populate them. But how to avoid the problem I had earlier with validation? The answer is multiple mappings. So if I have an Action, EditUserAction, I might have two mappings as such:

<action
    path="/admin/initEditUser"
    type="com.company.action.EditUserAction"
    name="editUserForm"
    scope="request"
    parameter="dispatch"
    validate="false">
        <forward
name="initEditUser" path="/admin/editUser.jsp" redirect="false" />
</action>
   
<action
    path="/admin/editUser"
    type="com.company.action.EditUserAction"
    name="editUserForm"
    scope="request"
    validate="true"
    input="/admin/editUser.jsp"
    parameter="dispatch">
        <forward name="success"
path="/admin/index.html" redirect="false" />
        <forward
name="initEditUser" path="/admin/editUser.jsp" redirect="false" />
</action>

The first mapping has the correct form for the page, but with validate turned off. The second has it turned on. The first action would have a different dispatch than the second and would take care of initializing request attributes.


[BTW, is there a good way to just cut and paste XML into a blog? I.e. without having to escape all the tags?]

Tuesday, July 29, 2003

I'm currently finding it difficult to model complex interfaces and have them maintain state without being tightly coupled. For example, I've got a tabbed panel interface that decides which tab to show you based on a request param (it's stolen straight out of the Struts examples). That works great in that the contents of the tabs don't have to know they are being displayed inside a tab. However, one of these tabs contains a form. The problem is, when the form is submitted, the response doesn't return to that tab because the form doesn't include that "tab select" parameter. I could work around this by storing the selected tab in the session, but then the page wouldn't work if the user had more than one browser open. For the moment, I've bitten the bullet and added "selectedTab" as a parameter submitted by the form. And I guess it's not that bad a solution, since it doesn't affect the behavior of the form (I.e. the page would work fine outside a tabbed layout). Still, it feels wrong. I'll keep looking for a better solution.

Friday, July 25, 2003

I got Maven to send email notifications when tests fail. This should improve the usefulness of our JUnit suite since I doubt any of our developers were checking the build results manually on a daily basis. Getting it work was a bit of a challenge, but I had a lot of help from Brett Porter on the Maven users mailing list. He added the details of his response to the Maven Wiki here:

http://wiki.codehaus.org/maven/EmailTestReports?action=highlight&value=maven.xml

I made a couple of additions as well, to help Maven newbies like myself. I also modified junit-noframes.xsl to only show the failing tests. Have I mentioned how much I hate XSL? I'm sure it's powerful and all, but I always find myself guessing until the transformations work.

Wednesday, July 23, 2003

Here's my first attempt a blog.

I've been learning a lot about Struts lately and thought it would be good to write things down to pass on to my colleagues. It occurred to me that a blog might be the answer, so I'm going to give it a try. I'll jump right in to the things I learned today.

Initializing a form. Because Struts wants you to have an Action to handle every request, I was thinking I had to initialize my ActionForm in an Action in order to prepopulate data in JSP form. This isn't true and in fact it won't work if you have validation turned on (you are validating your forms, right?) . The trouble is, your Action is never reached if the form fails its validation check. Instead, the browser is sent to whatever page you have defined as the "input" for the Action (usually the .jsp with the <html:form>). The answer is to initialize the form by overriding ActionForm.reset(). Do whatever you need to prepopulate the form here. Then, define the actions like this:

<!-- Action to initialize the form -->
<action path="/initializeForm" forward="/myform.jsp" />

<!-- Action to save the data entered in the form -->
<action path="/saveForm"
input="/myform.jsp"
type="com.foo.MyForm"
validate="true" >
<forward name="success" path="/yay.html" />
</action>


The reset() gets called when the Form is instantiated. That happens in your JSP when the <html:form> tag is encountered. Incidentally, if your forms have request scope, doesn't that mean they'll be initialized twice? So the prepopulation data, which may not be needed on the server side, will have to be generated twice? Hmm. There must be a way to avoid that.

I tried to get the struts-el tags working today, and met with very limited success. It appears there is a bug in the Jasper JSP compiler JspC that causes it to choke on the struts-el tags if JspC is run outside of Tomcat. This happens when you either a) precompile your JSPs using Ant or b) try to compile your JSP in Netbeans. I do both of these frequently, so that pretty much rules out the use of these tags until this bug is fixed.