I spoke too soon. Well, only about one thing.

Giving a Controller the name MyObjectFormController does NOT mean that
Spring will automatically know that the Command / Model object you want to
use with that Controller is called MyObject. You have to tell it, manually. 

What was driving me nuts was that I didn't see WHERE to do this since none
of my other beans in dispatcher-servlet.xml had the following lines:

<property name="commandName" value="findStreetSection"/>
<property name="commandClass"
value="com.myco.myapp.model.FindStreetSection"/>

That's because it was being done in the FindStreetSectionFormController
constructor:

public FindStreetSectionFormController() { 
  setCommandClass(FindStreetSection.class); 
  setCommandName("findStreetSection"); 
} 

Since I started off using an AbstractFormController instead of a
BaseFormController (which extends SimpleFormController) I had left out the
constructor thus the definition of the Command class ...

My bad, lesson learned,
Bob


syg6 wrote:
> 
> Well I found my problem, more or less. It's obvious if you look at my
> code. This is what I was doing in showForm():
> 
> ...
> ModelAndView mav = new ModelAndView("findSections", "sections", sections);
> mav.addObject("streets",referenceData(request));
> return mav; 
> ...
> 
> 
> Nowhere was I actually returning the Model itself, a FindStreetSection
> object. I was only returning the reference data. 
> 
> The problem was also that I had thought out the problem wrong. What I want
> to do is:
> 
> 1. upon entering the page don't load ANYTHING, not Streets, not
> StreetSections, nothing
> 2. once the user enters a text to search for display a list of Streets
> with that text
> 3. once the user has selected a Street from the list (step 2) and entered
> a number of StreetSection to search for, display a list of StreetSections
> for that Street with a range of addresses that encompasses the number
> entered.
> 
> I wound up changing it like this, using onSubmit() rather than showForm():
> 
> public ModelAndView onSubmit() 
> {
>   List<StreetSection> sections = null;
>   FindStreetSection fss = (FindStreetSection) command; // command obj
> loaded in formBackingObject()
>               
>   ModelAndView mav = new ModelAndView("findstreetsection",
> "findStreetSection", fss);
>               
>   if (fss.getStreetName() != null)
>   {
>     mav.addObject("streets",
> streetManager.findByName(fss.getStreetName()));
>   }
>               
>   if (fss.getStreet() != null)
>   {
>     sections = streetSectionManager.findByNumber(fss.getStreet(),
> fss.getNumber());
>     mav.addObject("sections", sections);
>   }
> 
>   return mav;
> }
> 
> This did the trick. I was even able to get rid of the commandName and
> commandClass parameters in my applicationContext; Spring now knows what
> the Command is based on the name of my Controller.
> 
> Thanks for your help, I hope this post helps some lost soul like me
> someday ...
> 
> Bob
> 
> 
> 
> syg6 wrote:
>> 
>> I'll give this a try tomorrow at work (3-day weekend here in Barcelona
>> ...) But I am curious, why should this be necessary? According to
>> Spring's 'convention over configuration' rules, if I create any type of
>> FormController that uses a Command object (say MyObjectFormController),
>> it should use the MyObject Command object by default, correct? That's
>> what I thought anyway ... But even after hard-wiring it in my
>> applicationContext file it doesn't seem to like it ...
>> 
>> Anyway, as I said, I'll try your recommendation tomorrow. Many thanks!
>> 
>> Bob
>> 
>> 
>> 
>> mraible wrote:
>>> 
>>> On 9/21/07, syg6 <[EMAIL PROTECTED]> wrote:
>>>>
>>>> Well, not sure why this is necessary but I stuck this in my
>>>> dispatcher-servlet.xml:
>>>>
>>>> <property name="commandName" value="findStreetSection"/>
>>>> <property name="commandClass"
>>>> value="com.myco.myapp.model.FindStreetSection"/>
>>>>
>>>> and now when I debug commandClass is correct. But in my page I still
>>>> don't
>>>> have access to it. If I put something like this:
>>>>
>>>> <form:form method="post" action="findstreetsection.html"
>>>> id="findStreetSectionForm">
>>>>   <form:input path="idStreet" id="idStreet" cssClass="text medium"/>
>>>>
>>>> I get this error:
>>>>
>>>> Neither BindingResult nor plain target object for bean name 'command'
>>>> available as request attribute
>>> 
>>> Have you tried <form:form commandName="findStreetSection">?
>>> 
>>> Matt
>>> 
>>> 
>>>>
>>>> The fact that I have to manually tell my Controller what its Command
>>>> class
>>>> is worries me, and is probably the problem. But I think my names are
>>>> all
>>>> correct. What's certain is, despite the fact that my commandClass seems
>>>> to
>>>> be set, it doesn't make it to the jsp.
>>>>
>>>> Bummer.
>>>>
>>>> Bob
>>>>
>>>>
>>>>
>>>> syg6 wrote:
>>>> >
>>>> > I tried doing it with showForm() and it kind of works:
>>>> >
>>>> > protected ModelAndView showForm(
>>>> > {
>>>> >   List<StreetSection> sections = null;
>>>> >
>>>> >   if (request.getParameter("id") != null)
>>>> >   {
>>>> >     String id = (String)request.getParameter("id");
>>>> >     Street street = streetManager.get(new Long(id));
>>>> >
>>>> >     Integer number = new Integer(request.getParameter("number"));
>>>> >     sections = streetSectionManager.findByNumber(street, number);
>>>> >   }
>>>> >
>>>> >   ModelAndView mav = new ModelAndView("findSections", "sections",
>>>> > sections);
>>>> >   mav.addObject("streets",referenceData(request));
>>>> >   return mav;
>>>> >
>>>> > }
>>>> >
>>>> > showForm() is called, and referenceData() is also called, thus
>>>> loading my
>>>> > streets. I am not sure if this is the best way to do it ... and I am
>>>> not
>>>> > sure if that second-to-last line, mav.addObject() should be mav.put()
>>>> > instead ... both seem to work ...
>>>> >
>>>> > But now in my page I don't have access to the Command (Model) object.
>>>> In
>>>> > theory, naming my Controller FindStreetSectionController, because of
>>>> > conventions, will automatically use my FindStreetSection object,
>>>> right?
>>>> > But when I debug and look at this.commandClass it is null.
>>>> >
>>>> > What am I doing wrong?
>>>> >
>>>> > Thanks,
>>>> > Bob
>>>> >
>>>> >
>>>> > syg6 wrote:
>>>> >>
>>>> >> I've been messing with this issue for a while. Basically I want to
>>>> be
>>>> >> able to search for StreetSections. Each StreetSection has a Street
>>>> and a
>>>> >> range of numbers. When you enter the search page the first time you
>>>> see a
>>>> >> list of Streets. Select one and enter a number and it will show you
>>>> a
>>>> >> list of StreetSections.
>>>> >>
>>>> >> Originally I wanted to do this without a Model object. But when I
>>>> made my
>>>> >> FindStreetSectionsController with an AbstractController I noticed
>>>> that
>>>> >> the referenceData() method, which I use to load all Streets, wasn't
>>>> being
>>>> >> called. That's because it is only called when you use a
>>>> *FormController
>>>> >> and call showForm() or a method that calls showForm() (like
>>>> onSubmit()).
>>>> >> Eventually I got it working but was calling referenceData() by hand,
>>>> >> which I thought was ugly. But, I thought, I can't use a
>>>> *FormController
>>>> >> because I am not using a Command (Model) object.
>>>> >>
>>>> >> After further thought though I realized that on the search page I
>>>> always
>>>> >> have a form with two fields - idStreet and number - the stuff to
>>>> search
>>>> >> for, so I decided to create a FindStreetSection Model object with
>>>> those
>>>> >> two fields , and that way I'd be able to use a BaseFormController
>>>> and
>>>> >> theoretically load automagically the Streets with referenceData().
>>>> >>
>>>> >> But I have a problem - I am not sure what method to implement in my
>>>> >> Controller. I have tried implementing both formBackingObject() and
>>>> >> onSubmit() but my test is failing. Here is my Controller:
>>>> >>
>>>> >> protected Object formBackingObject()
>>>> >> {
>>>> >>   FindStreetSection fss = new FindStreetSection();
>>>> >>   String id = request.getParameter("id");
>>>> >>   String number = request.getParameter("number");
>>>> >>
>>>> >>   if (!StringUtils.isBlank(id))
>>>> >>   {
>>>> >>     fss.setIdStreet(new Long(id));
>>>> >>     fss.setNumber(new Integer(number));
>>>> >>   }
>>>> >>
>>>> >>   return fss;
>>>> >> }
>>>> >>
>>>> >> public ModelAndView onSubmit()
>>>> >> {
>>>> >>
>>>> >>   List<StreetSection> sections = null;
>>>> >>   FindStreetSection fss = (FindStreetSection) command;
>>>> >>
>>>> >>   if (ft.getIdStreet() != null)
>>>> >>   {
>>>> >>     Street street = streetManager.get(fss.getIdStreet());
>>>> >>     sections = streetSectionsManager.findByNumber(street,
>>>> >> fss.getNumber());
>>>> >>   }
>>>> >>
>>>> >>   return new ModelAndView("findStreetSections", "sections",
>>>> sections);
>>>> >> }
>>>> >>
>>>> >> And here is my test:
>>>> >>
>>>> >> public void testSearch() throws Exception
>>>> >> {
>>>> >>   MockHttpServletRequest request =
>>>> newGet("/findstreetsection.html");
>>>> >>   request.addParameter("id", "1");
>>>> >>   request.addParameter("number", "196");
>>>> >>
>>>> >>   ModelAndView mav = c.handleRequest(request, new
>>>> >> MockHttpServletResponse());
>>>> >>   ModelMap m = mav.getModelMap();
>>>> >>
>>>> >>   assertNotNull(m.get("sections"));
>>>> >>   assertTrue(((List) m.get("sections")).size() > 0);
>>>> >> }
>>>> >>
>>>> >> formBackingMethod() is being called but onSubmit() is not, thus my
>>>> test
>>>> >> fails saying sections is null. I think my test is correctly written,
>>>> I am
>>>> >> just not sure which method I need to implement in my Controller.
>>>> >> onSubmit() doesn't seem to be it. Looking at other (form) tests, in
>>>> order
>>>> >> to get onSubmit() to be called it seems you have to do something
>>>> like
>>>> >> this:
>>>> >>
>>>> >> request = newPost("/findstreetsection.html");
>>>> >> super.objectToRequestParameters(fss, request);
>>>> >> request.addParameter("number", "198");
>>>> >>
>>>> >> in order for onSubmit() to be called. I tried this as well but no
>>>> go.
>>>> >> Anyway I never need to do any kind of save, update or delete, I
>>>> simply am
>>>> >> using a Command (Model) object to making searching easier. So which
>>>> >> method to I need to implement in my Controller to get this to work?
>>>> >>
>>>> >> Thanks,
>>>> >> Bob
>>>> >>
>>>> >
>>>> >
>>>>
>>>> --
>>>>
>>>> View this message in context:
>>>> http://www.nabble.com/How-to-write-a-controller-and-test-for-%27find%27-functionality-tf4496287s2369.html#a12824550
>>>>
>>>> Sent from the AppFuse - User mailing list archive at Nabble.com.
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>>>
>>>>
>>> 
>>> 
>>> -- 
>>> http://raibledesigns.com
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>> 
>>> 
>>> 
>> 
>> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/How-to-write-a-controller-and-test-for-%27find%27-functionality-tf4496287s2369.html#a12897638
Sent from the AppFuse - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to