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]