views:

458

answers:

2

Hi,

I am very new to Spring and I have been given some basic instructions to move some code into a new project that uses Spring and I am having trouble with the SimpleFormController (which I was instructed to user).

I have a page and when it loads it has a drop down with data populated from the DB. A list of "messages" is retrieved from the DB and passed as an attribute to the JSP and then the drop down is populated. When one of these "messages" is selected a form appears below the drop down and is populated with the appropriate data. No DB call is done as all the data is returned when the page is loaded. This is all done with jQuery. The form elements can be changed and saved to the DB when the update button is clicked.

At the moment the code is a portlet and the doView method contains the logic to retrieve the messages and pass them to the JSP. The processAction method saves the changes.

I cannot figure out which methods of the SimpleFormController. I have been told to use onSubmitAction for the update but the person who showed me what to do wasn't' sure what method I use to get the data when the page first loads, to save that data/model and to retrieve it in the JSP. I will be using the Spring command/form to save the changes a message but I will not be using it to populate the drop down and the form fields.

Apologies if this sounds like a stupid question. I have been looking up tutorials but I'm not finding the answers I need - possible because I am unsure what the question is.

Thanks in advance for any help Caroline

A: 

I haven't done this in a while, but let's see if I remember correctly. The SimpleFormController has an object attached which it will display. It will make the fields of this object automatically appear in your request (the simple ones at least).

To attach an object type to a SimpleFormController, you need to use the setCommandName and setCommandClass methods (I used to call them in the constructor). You will then need to implement the formBackingObject method - this is where you retrieve the object (from the DB for example) and set it in the controller.

To process submissions, you implement onFormSubmit - there you have access to a command object which has all the new values from your html form (Spring binds request values to your command object automatically). You'll probably want to commit changes to the database in this method.

You can add other parameters than what the command object fields in the request. In particular, it is useful to know that handleRequest is called first, and showForm is called last from what I remember. You need to check the documentation - I think the Spring guys recommend a special method where to add special parameters (can't remember what that is, I remember having some trouble using it).

If you have special objects in your command object that spring does not know how to interpret when displaying the jsp (I had a byte value which translated to days of week selected from a checkbox set of days of week), you can write your own binders and attach them to the parameters they link to by implementing the initBinder method.

Hope this helps. Things might have changed since I used this (roughly 8 months), but otherwise the idea was pretty simple once you took the time to go through the Spring code & documentation.

laura
A: 

It sounds like the idea is that the form backing object binds to the form, but the initial data for the form isn't loaded when the page loads (which is what you would use the formBackingObject method for). Instead, you want to pre-load some other data that doesn't go in the form backing object (the list of "messages") and the form will get initialized via Ajax based on that drop-down).

So what you want to use, I think, is the referenceData method. This allows you to put any objects you want into the request so they can be accessed from the JSP. You create a map and insert, say, a list of Message objects with a key of "messageList" into the map. Then you can just get the messages, within the JSP, by referencing ${messageList}.

JacobM
Will the referenceData method be called automatically on loading the page? I got half a solution by creating 2 controllers, one for when the page loads (an abstractController) and I implemented the handleRenderRequestInternal method. This worked in that my data came back and I populated my drop down. But when I modify the data and hit update it is not going into my onSubmitAction of my SimpleFormController. Instead it is going back in to my handleRenderRequestInternal. I would prefer to do both methods in one controller (SimpleForm) but not sure which method is called on page load
Caroline
Both formBackingObject and the referenceData will be called on page load every time in a SimpleFormController. There's a very useful chart of the SimpleFormController "lifecycle" at http://longgoldenears.blogspot.com/2007/07/simpleformcontroller-workflow-lifecycle.html
JacobM
ok, I got the referenceData to work now my problem is that on submit of my form it goes to the referenceData method and not the onSubmitAction method.
Caroline
That implies that it doesn't know it's a form submit. You may need to override isFormSubmission(); if there's something in the Request you can check to verify whether it's a form submission (e.g. if a certain parameter is populated, it must be a form submission).
JacobM
why would it not know about the form. Do you mean override the isFormSubmission() to debug or to make it work permanently? I'm not sure there is anything in the request, apart from the form submission??? I am so frustrated with this. It works fine and then I was told to move it to a new portlet application and use Spring and now I pretty much have to rewrite the entire thing. Deadline for this to be done was today but I will be still here pulling my hair out this time next week by the looks of things.
Caroline
Sorry it's been such a pain. I can testify that once you get the hang of it Spring really does make your life easier. Anyway, the controller decides whether it's a form submission based on whether the request is a POST. In some cases, though, that's not the right criteria, and that's when you override isFormSubmission (permanently).
JacobM
Well, I am specifying that it is a post but in HTTPwatch I see that my post is being redirected to a GET. No idea why but maybe that is my problem
Caroline
Yes, that is almost certainly what is causing the issue with not hitting onSubmitAction. Can you tell where the redirect is happening (e.g. is it reaching your server before the redirect or after)?
JacobM
I'm not sure to be honest..... I have a breakpoint set in referenceData and processAction. The post is being redirected to a get and then the breakpoint in referenceData is being hit.
Caroline
Got it fixed finally. Turned out there was an issue with a date being passed in the form and an exception was being thrown but not being handled. Read somewhere that if there is an exception thrown then the request will redirect! Hopefully it will be easier from now on! Thanks for the help. The referenceData method worked a treat!
Caroline
Glad to hear it!
JacobM