You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Scott Van Wart <sc...@indosoft.com> on 2006/08/14 21:30:46 UTC

[SOLVED?] Re: Map-based nested bean--No bean specified?

OK so I replaced the 'getChild( String id )' method with the following:

  public ChildPerson getChild( String id )
  {
    ChildPerson child = this.children.get( id );
    if ( child == null )
    {
      child = new ChildPerson();
      this.children.put( id, child );
    }
    return child;
  }

And my problems were all solved.  I tried this solution before in my 
previous post, but made a typo, which caused it to fail with the same 
error, so I thought my previous solution simply didn't work.  It wasn't 
until I tried this solution with my concrete example below that I 
noticed the typo (was creating a new child, putting it into the map, but 
then STILL returning null.  Note that setChild( String id, ChildPerson 
child ) never gets called by the framework.

So my final question: Is all this a good idea? :)

- Scott

Scott Van Wart wrote:
> I posted on this before, so I thought I'd post a more concrete example 
> this time.
>
> I'm using a map-based nested bean, and I'm getting the following error:
>
> java.lang.IllegalArgumentException: No bean specified
>     org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptor(PropertyUtilsBean.java:751) 
>
>     org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:937) 
>
>     org.apache.commons.beanutils.BeanUtilsBean.populate(BeanUtilsBean.java:811) 
>
>     org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:298)
>     org.apache.struts.util.RequestUtils.populate(RequestUtils.java:493)
>     (add nausea)
>
> So I whipped up an example.  I have a DoTestAction that populates the 
> form and sticks it in a request.  The form is called TestForm and 
> looks like this:
>
>  package test.form;
>
>  import java.util.Map;
>  import java.util.Set;
>  import java.util.TreeMap;
>
>  import org.apache.struts.action.ActionForm;
>
>  public class TestForm extends ActionForm
>  {
>
>    public static final long serialVersionUID = 1;
>
>    private String firstName;
>    private String lastName;
>      private Map<String, ChildPerson> children;
>      public TestForm()
>    {
>      this.firstName = "";
>      this.lastName = "";
>      this.children = new TreeMap<String, ChildPerson>();
>    }
>
>    public Set<String> getChildIds()
>    {
>      return this.children.keySet();
>    }
>      public Map<String, ChildPerson> getChildren()
>    {
>      return this.children;
>    }
>
>    public void setChildren( Map<String, ChildPerson> children )
>    {
>      this.children = children;
>    }
>
>    public String getFirstName()
>    {
>      return this.firstName;
>    }
>
>    public void setFirstName( String firstName )
>    {
>      this.firstName = firstName;
>    }
>      public String getLastName()
>    {
>      return this.lastName;
>    }
>      public void setLastName( String lastName )
>    {
>      this.lastName = lastName;
>    }
>
>    public void setChild( String id, ChildPerson child )
>    {
>      this.children.put( id, child );
>    }
>      public ChildPerson getChild( String id )
>    {
>      return this.children.get( id );
>    }
>    }
>
>
> The populate action looks like this:
>
>  package test.action;
>
>  import javax.servlet.http.HttpServletRequest;
>  import javax.servlet.http.HttpServletResponse;
>
>  import org.apache.struts.action.Action;
>  import org.apache.struts.action.ActionForm;
>  import org.apache.struts.action.ActionForward;
>  import org.apache.struts.action.ActionMapping;
>
>  import test.form.ChildPerson;
>  import test.form.TestForm;
>
>  public class DoTestAction extends Action
>  {
>
>    @Override
>    public ActionForward execute( ActionMapping mapping, ActionForm form,
>        HttpServletRequest request, HttpServletResponse response )
>      throws Exception
>    {
>
>      TestForm testForm = new TestForm();
>
>      ChildPerson child = new ChildPerson();
>      child.setFirstName( "First 1" );
>      child.setLastName( "Last 1" );
>      testForm.setChild( "1", child );
>
>      child = new ChildPerson();
>      child.setFirstName( "First 2" );
>      child.setLastName( "Last 2" );
>      testForm.setChild( "2", child );
>
>      request.setAttribute( "testForm", testForm );
>          return mapping.findForward( "default" );
>
>    }
>
>  }
>
> While the JSP itself looks like this:
>
>    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
>    <%@ taglib uri="/tags/struts-html" prefix="html" %>
>      <%@ page language="java" contentType="text/html; charset=UTF-8"
>        pageEncoding="UTF-8"%>
>      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
>      <html>
>        <head>
>            <meta http-equiv="Content-Type" content="text/html; 
> charset=UTF-8">
>            <title>Test</title>
>        </head>
>        <body>
>              <html:form action="/test">
>                          First Name: <html:text property="firstName" 
> /><br>
>                              Last Name: <html:text property="lastName" 
> /><br>
>                  <c:forEach var="childId" items="${testForm.childIds}">
>                                  Child #${childId} First Name: 
> <html:text property="child(${childId}).firstName" /><br>
>                                      Child #${childId} Last Name: 
> <html:text property="child(${childId}).lastName" /><br>
>                              </c:forEach>
>                  <html:submit />
>                      </html:form>
>          </body>
>    </html>
>
> My struts-config.xml (though I'm not sure this would help) has this 
> for the forms and actions:
>
>    <form-bean name="doTestForm"
>            type="test.form.DoTestForm" />
>
>    <form-bean name="testForm"
>            type="test.form.TestForm" />
>
>    ...
>
>    <action path="/doTest" type="test.action.DoTestAction" 
> name="doTestForm" scope="request"
>      validate="false">
>      <forward name="default" path="/test.jsp" />
>    </action>
>
>    <action path="/test" type="test.action.TestAction" name="testForm" 
> scope="request"
>      validate="false">
>      <forward name="default" path="/test.jsp" />
>    </action>
>
> I won't bother to post TestAction (/testAction) as it doesn't even get 
> to that point.  Am I doing this the right way?  Is this sort of thing 
> even possible?  It seems such a natural way (against everything else) 
> to express what I'm trying to do, but doesn't seem to be working.  
> BeanUtils doesn't even recognize TestForm.setChild() and 
> TestForm.getChild() as being property accessors!
>
> Any help would be appreciated!
>
> Thanks,
>  Scott
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org