No takers on this? If I am renderin a select box in JSP with selectTag and optionsCollectionTag, can my form bean store the selected options in a collection? (instead of an array, which seems to work fine)


From: "Janne Mattila" <[EMAIL PROTECTED]>
Reply-To: "Struts Users Mailing List" <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: OptionsCollectionTag with ActionForm and a collection attribute
Date: Mon, 09 Aug 2004 09:54:57 +0000

I am just studying the basic things about Struts, and have some trouble getting selectTag and optionsCollectionTag work as I would expect. Intention is to have two properties in a form: allChoices, that is a collection holding all possible choices for the select tag, and selectedChoicesCollection, that contains the currently selected ones. Each choice is modelled by a class Choice, that contains two attributes, id for identifying the selection and name, which is displaed to the user. SelectedChoicesCollection contains only the values of the Choices (as having it contain Choice objects did not seem to work at all).

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&gt;Preferences&gt;Java&gt;Code Generation&gt;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]


_________________________________________________________________
The new MSN 8: smart spam protection and 2 months FREE* http://join.msn.com/?page=features/junkmail



--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to