Nov 11th, 2005, 05:18 AM
Handling required arguments in form controller during GET
I have a form controller (which extends SimpleFormController) which is passed an Id parameter during the get request. (for example, http://.../myapp/myobject/edit.html?id=120). The form is expected to retrieve the object from database using Id and return it as command object for editing. When the object is returned during submission, the controller updates the data in the database.
If the id parameter is missing during edit request or there is some problem accessing the requested object (because it does not exist in database or due to some access restriction in the business layer), I would like to return the user back to the page where he was (and he could be doing this from multiple places in the application) with an error message.
What is the right way to do this? Is there a best practice to accomplish this.
I just started using Spring a week back and I appreciate your help.
Thanks in advance.
Nov 11th, 2005, 06:44 AM
You probably don't want to present the Hibernate object as a command object to the controller for direct editing. There are two conflicting views on this, but in my opinion it is safer to create a non-Hibernate POJO to copy the Hibernate entity properties into, send that as a command object, and then copy the properties back later before it is explicitly saved. Otherwise you can end up with the problem you are seeing.
You don't have to write all the property copying code manually, you can use Jakarta Commons BeanUtils to do this for you.
See this discussion for more info - http://forum.springframework.org/showthread.php?t=19488
Nov 11th, 2005, 07:04 AM
In answer to the first part of your question: Yes, you can get the SimpleFormController to handle a normal GET request by overriding the isFormSubmission method to return a true for GET requests (by default, it only returns true for POST). BUT I believe you should use a ViewController to handle just the retrieval and displaying of data, i.e. when you only have an Id parameter.
For the second part: If the form submission is missing an Id parameter then that's a sounds like a job for the onBindAndValidate method or to use a Validator.
For the situation where there's an error thrown by some service object then that's a bit more complicated and would probably have to involve looking up the request's referring url and changing the form's formView property. I'd have to do experimenting first...
Nov 11th, 2005, 08:11 AM
Thank you very much for the suggestions.
I am passing the id as a request parameter. I am able to get the object from database in the formBackingObject(). But my issue is with returning appropriate error message if the id was missing during GET request to the form controller (or I don't want the user to access the object with the given id and hence, don't want to return that object). The examples I have seen returns a new command object. But I don't want the user to see an empty form, but be redirected to his previous page with an error message.
This redirection is the area where I have problem with. The only place I could think of doing a redirection would be by overriding showForm(), because that seems to be the only method during the GET request that can return a different view.
But I am not comfortable with doing this kind of checking in the showForm(). I don't think it is the right place.
May be I should look at an interceptor to do appropriate checking before the request is passed on to my form controller. What do the experts recommend?
Thanks once again guys for the instant response.
Nov 12th, 2005, 02:46 AM
Just a thought (and it's not really answering your question): When the user sees this error message, what do you expect them to *do* about it? Presumably you're not expecting them to know the ID of the object they're editing, so a failure to supply an ID indicates an application error (i.e. you've coded the link wrong, or whatever).
Originally Posted by mgskumar
In which case, there's not much point trying to send them back to the previous step to try and resolve the error and continue the process. There's nothing that they can do in this situation except give up.
So, why not just throw an exception and return them an HTTP 500 error page ? (A nice-looking one, obviously)
Nov 15th, 2005, 07:53 AM
mgskummer; As a general principle; a redirect in a controller is the wrong place for it IMO (although some of the spring gurus do it ).
I would always make your controllers agnostic (as far as possible) of the view they are returning. Modifying your view from a RedirectView to an InternalResourceView etc. should not require modification of your controller.
Nov 15th, 2005, 07:55 AM
Also, as Chris stated, the right thing to do depends upon your expectation of what the user can do.
If you are expecting users to enter /yourcontroller?id=xyz then a nice page stating "no product can be found" should be displayed. If (like most of us) you are not expecting the user to manually enter the id, and only *your application* can specify the id, then as Chris states, it is by definition an exceptional state, so throw an exception message.
If, BTW you are expecting users to enter the url, you might want to think about implementing (or adopting) a RESTful interface.