You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Frederic Dernbach <fr...@free.fr> on 2003/10/05 16:46:24 UTC

Help needed : cannot resend an indexed property to request

Hello, 

I experience big difficulties resend an indexed property of a form as
part of a request. 

I build a super-simple code sample to share with you so you can help me
"find the trick". 

I have a form named TestForm; It has one property named 'beans' that is
an array of TestBean. TestBean is a bean that as two strings properties
: 'b' and 'c'. I put the class code below. 

I have two struts actions : '/Test' and '/Validate'. 
- '/Test' populates the form (especially the 'beans' property) and
forwards to the JSP 'test.jsp'. 
- 'test.jsp' displays basic a form property as well as a list (indexed
property).
- 'Validate' is the action called by the form included in 'test.jsp. It
does nothing but forward back to the JSP 'test.jsp'. 
I included the code of those two actions as well as the declarations in
struts-config.xml. 


HERE IS MY PROBLEM :

If I use the 'test.jsp' file below, I get an exception
InvokationTargetException when I hit the validate button (submit button
of the form). I aded the JSP an the exception from BeanUtils.populate()
below.

<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html>
<head>
<title>Test Indexed property</title>
</head>
<body>
	
<html:form action="/Validate.do">
<html:text property="a" />
<table width="650" border="0" cellspacing="0" cellpadding="0">
<tr align="left">
	<th>B</th>
	<th>C</th>
</tr>		
<logic:iterate name="testForm"
	property="beans"
	id="aBean"
	indexId="i"
	type="com.rubis.web.system.TestBean">
	<tr align="left">
	<td>
	<html:text name="testForm" property="<%=\"bean[\"+i+\"].b\"%>"/>
	</td>
	<td>
	<html:text name="testForm" property="<%=\"bean[\"+i+\"].c\"%>"/>
	</td>
	</tr>
</logic:iterate>
<html:submit>Validate</html:submit>	
</table>		
</html:form>
</body>
</html>


java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at
org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:493)
	at
org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:428)
	at
org.apache.commons.beanutils.PropertyUtils.getNestedProperty(PropertyUtils.java:770)
	at
org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:801)
	at
org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:881)
	at org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:808)


QUESTION : how should I write my JSP in order to have the form populated
correctly by Struts before entering the 'Validate' action ? How can I
ensure than the indexed property is resend in the request ?


I tried a modified version of the JSP, with no success (I print here the
<logic:iterate> tag only). The JSP displays OK, but when I hit the
submit button, Struts does not find any collection :

<logic:iterate name="testForm" property="beans" id="aBean" >
	<tr align="left">
	<td>
	<html:text name="aBean" property="b"/>
	<html:text name="aBean" property="c"/>
	</td>
	</tr>
</logic:iterate


I tried another version. This time, I get a NullPointerException :
 
<logic:iterate name="testForm" property="beans" id="beans">
	<tr align="left">
	<td>
	<html:text name="beans" property="b" indexed="true"/>
	</td>
	<td>
	<html:text name="beans" property="c" indexed="true"/>
	</td>
	</tr>
</logic:iterate>

java.lang.NullPointerException at
org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:515)



Thanks in advance for your help.

Fred

************************ TestForm.java ****************************** 

package com.rubis.web.system; 
import javax.servlet.http.HttpServletRequest; 
import org.apache.struts.action.ActionMapping; 
import org.apache.struts.action.ActionForm; 
import com.rubis.web.system.TestBean; 

public class TestForm extends ActionForm implements java.io.Serializable
{ 
public String getA() { 
return a; 
} 
public void setA(String a) { 
this.a = a; 
} 
public TestBean[] getBeans() { 
return beans; 
} 
public void setBeans(TestBean[] beans) { 
this.beans = beans; 
} 
public TestBean getBean(int index) { 
return beans[index]; 
} 
public void setBean(int index, TestBean bean) { 
beans[index] = bean; 
} 
public void reset(ActionMapping mapping, HttpServletRequest request) { 
a = null; 
beans = null; 
} 

private String a; 
private TestBean[] beans; 

} 

******************** TestBean.java *********************** 
package com.rubis.web.system; 

public class TestBean { 

public String getB() { 
return b; 
} 
public void setB(String b) { 
this.b = b; 
} 
public String getC() { 
return c; 
} 
public void setC(String c) { 
this.c = c; 
} 
private String b; 
private String c; 

} 

*************** struts-config.xml ******************** 
>action path="/Test" 
type="com.rubis.web.system.TestAction" 
scope="request" 
name="testForm" 
validate="false" 
attribute="testForm"> 
	<forward name="success" path="/test.jsp" /> 
</action>
 
<action path="/Validate" 
type="com.rubis.web.system.ValidateAction" 
scope="request" 
name="testForm" 
validate="false" 
attribute="testForm"> 
	<forward name="success" path="/test.jsp" /> 
</action> 


************** TestAction.java ************************* 
package com.rubis.web.system; 
import java.io.IOException; 
import javax.servlet.ServletException; 
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.ActionMapping; 
import org.apache.struts.action.ActionForward; 
import org.apache.log4j.Logger; 

import com.rubis.web.system.TestForm; 

public class TestAction extends Action { 

public ActionForward execute( ActionMapping mapping, 
ActionForm form, 
HttpServletRequest request, 
HttpServletResponse response) 
throws IOException, ServletException { 

	logger.info("execute() : Starting with form : " + form); 

	TestForm testForm = (TestForm) form; 
	testForm.setA("a"); 
	TestBean bean1 = new TestBean(); 
	bean1.setB("b1"); 
	bean1.setC("c1"); 
	TestBean bean2 = new TestBean(); 
	bean2.setB("b2"); 
	bean2.setC("c2"); 
	TestBean[] beans = new TestBean[2]; 
	beans[0] = bean1; 
	beans[1] = bean2; 
	testForm.setBeans(beans); 

	logger.info("execute() : Ending with form : " + form); 
	return (mapping.findForward("success")); 

} 

static private Logger logger = Logger.getLogger(TestAction.class); 
} 


************** ValidateAction.java ************************* 

package com.rubis.web.system;
import java.io.IOException;
import javax.servlet.ServletException;
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.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.log4j.Logger;

public class ValidateAction extends Action {
	
public ActionForward execute(	ActionMapping mapping,
		ActionForm form,
		HttpServletRequest request,
		HttpServletResponse response)
		throws IOException, ServletException {

	logger.info("execute() : form = " + form);
	
	return (mapping.findForward("success"));
			
}

static private Logger logger = Logger.getLogger(ValidateAction.class);

}




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