0

I have a class hierarchy where one class, say, Book is a base class for a more specific item, say ChildrensBook.

I need to present these items in a JSP form so that their fields can be edited. Book and ChildrensBook have so much in common that it seems reasonable for me to use a single controller and a single JSP form. In fact ChildrensBook is simply a Book with one extra field, say,ageGroup. The JSP displays an input box for this field only when editing instances of ChildrensBook

I've begun to write the code but I've hit a problem when the completed form is posted back to the MVC controller. Here is the method that handles the form:

@RequestMapping( value="*", method = RequestMethod.POST )
public String onSubmit( @Valid @ModelAttribute("entity") BookCommand command, BindingResult result, RedirectAttributes redirectAttributes, ModelMap model )
{ /* code not shown */ }

As you can see, I'm binding the form to a BookCommand but I need forms for children's books to bind to a ChildrensBookCommand object.

What's a good solution in this case? Creating another form / controller specifically for ChildrensBook would cause a lot of undesirable duplicated code. Creating another handler method with a ChildrensBookCommand instead of BookCommand fails, presumably because MVC cannot tell which one to use. Posting a children's book form to a different URL seems awkward, since I'm using a Spring <form:form ...> tag which automatically sets the form action URL.

Thanks for any advice.

Alex
  • 1,061
  • 2
  • 11
  • 19

1 Answers1

0

You can test which object you have when you render the JSP page and specify two different URL. There will be two method in your controller but you can call methods who are shared to avoid duplicate code.

In JSP something like

if(myobject is Book)
  <form action="urlForBook"/>
else
  <form action="urlForChildrenBook"/>

In Controller, something like

@RequestMapping( value="/book", method = RequestMethod.POST )
public String onBookSubmit( @Valid @ModelAttribute("entity") BookCommand command, BindingResult result, RedirectAttributes redirectAttributes, ModelMap model )
{ commonMethod(); }

@RequestMapping( value="/childrenbook", method = RequestMethod.POST )
public String onChildrenBookSubmit( @Valid @ModelAttribute("entity") BookCommand command, BindingResult result, RedirectAttributes redirectAttributes, ModelMap model )
{ commonMethod(); }

private commonMethod()
{ /* code goes here*/}
Mannekenpix
  • 744
  • 7
  • 15
  • Thanks, that worked. Using Spring form tags, I used ` ` – Alex May 14 '13 at 12:02
  • Anyone implementing this may be interested that if, as in my case, they use a separate command object (BookCommand, ChildrensBookCommand) in each mapped method, it becomes necessary to specify a validator for each command. How to do so is explained [here](http://stackoverflow.com/questions/14533488/addiing-multiple-validators-using-initbinder) – Alex May 14 '13 at 14:45