Map-based nested bean--No bean specified?
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 MapString, ChildPerson children; public TestForm() { this.firstName = ; this.lastName = ; this.children = new TreeMapString, ChildPerson(); } public SetString getChildIds() { return this.children.keySet(); } public MapString, ChildPerson getChildren() { return this.children; } public void setChildren( MapString, 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 titleTest/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
[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 MapString, ChildPerson children; public TestForm() { this.firstName = ; this.lastName = ; this.children = new TreeMapString, ChildPerson(); } public SetString getChildIds() { return this.children.keySet(); } public MapString, ChildPerson getChildren() { return this.children; } public void setChildren( MapString, 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 titleTest/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
Map-based nested bean
(Struts 1.2.9, Tomcat 5.5.17) I have something similar to the following in my ActionForm: public class MyForm extends ActionForm { public static class NestedBean { private String name; private String value; // String getName(), String getValue(), void setName( String ), void setValue( String ) } private MapString, NestedBean children = new TreeMapString, NestedBean(); // Map getChildren(), void setChildren( Map ) public NestedBean getChild( String key ) { return this.children.get( key ); } public void setChild( String key, NestedBean child ) { this.children.put( key, child ); } } I use it like so in the JSP: html:form action=/myAction html:text property=myForm.child(whatever).name / html:text property=myForm.child(whatever).value / /html:form Everything works fine until form submission. Then I get errors like No bean specified in the populate methods of BeanUtils. Looking at the property descriptors I see that it's not picking up the getChild and setChild accessors. Is this the right way to implement this? Am I still missing something? Thanks, Scott - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]