I have to actions, SimpleGetAction and SimpleSaveAction. User starts by calling a URL which maps to SimpleGetAction. This action populates the form object and moves on to the JSP page. This part works out as I excpect, and the correct choice(s) is highlighted. When user submits the form, SimpleSaveAction gets called - except that BeanUtils.populate throws an exception before action gets it's turn:
12:34:46,268 INFO [STDOUT] DEBUG [org.apache.struts.util.RequestUtils][1799] Get module name for path /SaveSimpleTest.do
12:34:46,268 INFO [STDOUT] DEBUG [org.apache.struts.util.RequestUtils][1821] Module name found: default
12:34:46,268 INFO [STDOUT] DEBUG [org.apache.struts.action.RequestProcessor][225] Processing a 'POST' for path '/SaveSimpleTest'
12:34:46,268 INFO [STDOUT] DEBUG [org.apache.struts.util.RequestUtils][764] Looking for ActionForm bean instance in scope 'request' under attribute key 'simp
eForm'
12:34:46,268 INFO [STDOUT] DEBUG [org.apache.struts.util.RequestUtils][839] Creating new ActionForm instance of type 'jannen.form.SimpleTestForm'
12:34:46,268 INFO [STDOUT] DEBUG [org.apache.struts.util.RequestUtils][844] --> jannen.form.SimpleTestForm selectedChoicesArray: selectedChoicesCollection:
3]
12:34:46,308 INFO [STDOUT] DEBUG [org.apache.struts.action.RequestProcessor][372] Storing ActionForm bean instance in scope 'request' under attribute key 'si
pleForm'
12:34:46,388 INFO [STDOUT] DEBUG [org.apache.struts.action.RequestProcessor][813] Populating bean properties from this request
12:34:46,388 ERROR [Engine] StandardWrapperValve[action]: Servlet.service() for servlet action threw exception
javax.servlet.ServletException: BeanUtils.populate
at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:1254)
at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:821)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:254)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)
12:34:46,919 ERROR [Engine] ----- Root Cause -----
java.lang.IllegalArgumentException: argument type mismatch
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.setSimpleProperty(PropertyUtils.java:1789)
at org.apache.commons.beanutils.PropertyUtils.setNestedProperty(PropertyUtils.java:1684)
at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:1713)
at org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:1019)
at org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:808)
at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:1252)
at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:821)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:254)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)
When storing selected ones in an array of ints instead of a collection of Integers, the example works. Since the view-part works also with collections, I believe collections should work also. Although I was not able to get a clear answer to this from the documentation.
Related code and configuration:
struts-config.xml:
<form-beans>
<form-bean type="jannen.form.SimpleTestForm" name="simpleForm" />
</form-beans>simpleTest.jsp:
<%@ page language="java" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-logic" prefix="logic" %> <!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <title><bean:message key="app.title" /></title> <html:base/> </head> <body bgcolor="#FFFFFF">
<html:errors />
<html:form action="/SaveSimpleTest" scope="request">
<!--
Array works fine
<html:select property="selectedChoicesArray" multiple="true" size="5">
<html:optionsCollection property="allChoices" value="id" label="name"/>
</html:select>
-->
<html:select property="selectedChoicesCollection" multiple="true" size="5">
<html:optionsCollection property="allChoices" value="id" label="name"/>
</html:select>
<html:submit/>
</html:form>
</body> </html>
Choice.java:
/* * Created on 9.8.2004 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package jannen.form;
import java.io.Serializable;
public class Choice implements Serializable {
public static final Choice ONE = new Choice(new Integer(1), "first");
public static final Choice TWO = new Choice(new Integer(2), "second");
public static final Choice THREE = new Choice(new Integer(3), "third");
public static final Choice HUNDRED = new Choice(new Integer(100), "number one hundred");
private Integer id;
private String name; public Choice() {
} public Choice(Integer id, String name) {
this.id = id;
this.name = name;
} public Integer getId() {
return id;
} public String getName() {
return name;
} public void setId(Integer i) {
id = i;
} public void setName(String string) {
name = string;
} public String toString() {
return this.getClass().getName() + ", id: " + id + ", name: " + name;
}
}SimpleGetAction.java:
package jannen.action;
import jannen.form.Choice; import jannen.form.SimpleTestForm; import java.util.ArrayList; import java.util.Collection; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping;
public class SimpleGetAction extends Action {
static Logger logger = Logger.getLogger(SimpleGetAction .class); /*
* Initialize form with default value and all available options
**/
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception { SimpleTestForm initialForm = new SimpleTestForm();
Collection allChoices = new ArrayList();
allChoices.add(Choice.ONE);
allChoices.add(Choice.TWO);
allChoices.add(Choice.THREE);
allChoices.add(Choice.HUNDRED); initialForm.setAllChoices(allChoices);
initialForm.setSelectedChoicesArray(new int[] { 3 }); Collection selectedChoicesCollection = new ArrayList();
selectedChoicesCollection.add(new Integer(3));initialForm.setSelectedChoicesCollection(selectedChoicesCollection);
request.setAttribute(mapping.getAttribute(), initialForm);
logger.debug("got form: " + form); return mapping.findForward("success");
}}
SimpleSaveAction.java:
package jannen.action;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping;
public class SimpleSaveAction extends Action {
static Logger logger = Logger.getLogger(SimpleSaveAction .class); public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception { logger.debug("got form: " + form); return mapping.findForward("success");
}}
SimpleTestForm.java:
package jannen.form;
import java.util.ArrayList; import java.util.Collection; import org.apache.log4j.Logger; import org.apache.struts.action.ActionForm;
public class SimpleTestForm extends ActionForm {static Logger logger = Logger.getLogger(SimpleTestForm.class);
// all possible choices
static Collection allChoices = new ArrayList(); // selected choices, using int array
int[] selectedChoicesArray = new int[] {}; // selected choices, using a collection of objects
static Collection selectedChoicesCollection = new ArrayList(); public int[] getSelectedChoicesArray() {
return selectedChoicesArray;
} public void setSelectedChoicesArray(int[] is) {
selectedChoicesArray = is;
} public Collection getAllChoices() {
return allChoices;
} public void setAllChoices(Collection collection) {
allChoices = collection;
} public Collection getSelectedChoicesCollection() {
return selectedChoicesCollection;
} public void setSelectedChoicesCollection(Collection collection) {
selectedChoicesCollection = collection;
} public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(this.getClass().getName());
buffer.append(" selectedChoicesArray: ");
if (selectedChoicesArray == null) {
buffer.append("null");
} else {
for (int i = 0; i < selectedChoicesArray.length; i++) {
buffer.append(" " + selectedChoicesArray[i]);
}
}
buffer.append(" selectedChoicesCollection: ");
buffer.append(selectedChoicesCollection); return buffer.toString();
}
}_________________________________________________________________
Help STOP SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]

