style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Struts 1.3.8 Listas!!!

Hola que tal chavos.

Aquí de nuevo solicitando consejos y/o sugerencias:

Les cuento, estoy utilizando struts y mi problema es el siguiente:

Lleno una lista de empleados desde un action de la siguiente forma:

<logic:iterate id="miembros" name="MiembrosForm" property="listaMiembros">
     <tr>
        <td><html:text name="miembros" property="idMiembro" />
        <td><html:text name="miembros" property="nombreMiembro" />
        <td><html:file name="miembros" property="adjuntoUno" />
        <td><html:file name="miembros" property="adjuntoDos" />
     </tr>
</logic:iterate>

Lo que quiero es modificar los datos de la lista y enviarla de nuevo a otro action para hacer la persistencia, el problema es que no llegan los datos, mi lista esta en null; en mi actionForm tengo esto para recibir el arreglo de empleados desde el JSP como sigue:

        private ArrayList<Miembros> listaMiembros;

        public ArrayList getListaMiembros() {
                return listaMiembros;
        }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }

En mi Action tengo lo siguiente:

MiembrosPrincipalForm formMiembros = (MiembrosPrincipalForm)form;
               
                listaMiembros = formMiembros.getListaMiembros();
               
                if(listaMiembros.size() > 0){
                        System.out.println("Iterando...");
                        for(Miembros miembro : listaMiembros){
                                System.out.println("ID miembro -> " + miembro.getIdMiembro());
                                System.out.println("Nombre miembro -> " + miembro.getNombreMiembro());
                                System.out.println("Adjunto 1 miembro -> " + miembro.getAdjuntoUno().getFileName());
                                System.out.println("Adjunto 2 miembro -> " + miembro.getAdjuntoDos().getFileName());
                               
                        }
                }else {
                        System.out.println("No existen datos");
                }

Simplemente se pasa a no existen datos, no entiendo porque??? es como si no se setearan los nuevos datos a la lista, existe alguna otra forma de enviar una lista a un action? Si alguien la sabe le agradecería que me dijera.

Gracias, saludos.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de WinDoctor

Falta metodo set con index

En el form debes tener una lista y dos métodos como estos;

private List matriz;
...........
public void setMatrizMiembros( int index, Miembros bean )       {
                matriz.set( index, bean );
        }
       
        public Miembros getElementoMiembro( int index ) {
                return (Miembros)matriz.get( index );
        }

donde Miembros es el tipo de objeto que almacena la lista. De esta forma, cuando se haga un submit se enviaran cada uno de los "registros" que corresponderán con un índice del arreglo.

Imagen de ghosttigger1203

??? matriz Miembros

Hola WinDoctor, gracias por tu respuesta.

De hecho ya tenia esos métodos en el action form como sigue:

        private ArrayList<Miembros> listaMiembros;

        public ArrayList getListaMiembros() {
                return listaMiembros;
        }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }
       
        public Miembros getListaMiembros(int index) {
                return (Miembros)listaMiembros.get(index);
        }

        public void setListaMiembros(int index, Miembros miembro) {
                this.listaMiembros.add(listaMiembros);
        }

pero me marca error diciendo: no existe un getter para listaMiembros, es como lo mostre??? o para los 2 métodos extra con el index deben llevar nombres diferentes???

Gracias...

Imagen de neko069

Mira, yo no sé nada de nada

Mira, yo no sé nada de nada de Struts, pero al parecer el error está en que deberías de tener un getListaMiembros( ) así sin parámetros, si lo vas a sobrecargar, pues no sé si te tire errores, pero de entrada, al parecer por convención se requiere usar un getter como debería, o sea, sin parámetros....

Imagen de WinDoctor

No recuerdo bien pero creo en

No recuerdo bien pero creo en el JSP debe ser algo asi

     
<logic:iterate id="m" name="listaMiembros">
<tr>
        <td><html:text name="m" property="idMiembro" indexed="true" />
..........

ó algo asi;

<logic:iterate name="TuFormulario" property="listaMiembros" id="m" indexId="i">  
  <html:text property='<%="m["+i+"]" %>' />  
</logic:iterate>

perdón por el scriptlet....

de preferencia pon otro nombre a los método que tienen el index y ese es el que debes poner en al construir en StringBuilder.

Otra forma es utilizando algo asi:

 <nested:iterate name="TuFormulario" property="listaMiembros" id="item">
                    <tr>
                        <td><nested:text property="idMiembro"/></td>
..............
................

Con lo anterior no hace falta declarar los métodos con un parámetro index...

http://www.experts-exchange.com/Programming/Languages/Java/J2EE/JSP/Q_21...

Imagen de ghosttigger1203

Aún sin éxito

Hola WinDoctor, estuve ocupado un buen ratito por eso no respondía, pero aquí estoy de nuevo.

Respecto a lo del JSP y los controles dinamicos ya lo intente de distintas formas, utilizé las que posteaste pero estoy como al principio, no logro que lleguen los datos al action. Mira te pongo lo que intenté.
JSP

<nested:iterate name="MiembrosForm" property="listaMiembros" id="miembros">
        <tr>
                <td><nested:text name="miembros" property="idMiembro" /></td>
                <td><nested:text name="miembros" property="nombreMiembro" /></td>
                <td><nested:file name="miembros" property="adjuntoUno" /></td>
                <td><nested:file name="miembros" property="adjuntoDos" /></td>
        </tr>
</nested:iterate>

FORM

        private ArrayList listaMiembros;

        public MiembrosPrincipalForm() {
                 listaMiembros = new ArrayList();
        }

        public ArrayList getListaMiembros() {
                return listaMiembros;
        }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }

ACTION

         MiembrosPrincipalForm formMiembros = (MiembrosPrincipalForm)form;
         listaMiembros = formMiembros.getListaMiembros();

         System.out.println("TamArrayMiembros -> " + listaMiembros.size());

         if(listaMiembros.size() > 0){
                System.out.println("Iterando...");
                for(Object miembro : listaMiembros){
                        m = (Miembros)miembro;
                        System.out.println("ID miembro -> " + m.getIdMiembro());
                        System.out.println("Nombre miembro -> " + m.getNombreMiembro());
                        System.out.println("Adjunto 1 miembro -> " + m.getAdjuntoUno().getFileName());
                        System.out.println("Adjunto 2 miembro -> " + m.getAdjuntoDos().getFileName());
                               
                }
        }else {
                System.out.println("Creando...");
                Miembros miembro = new Miembros();

                miembro.setIdMiembro(0);
                miembro.setNombreMiembro("Jonathan");
                listaMiembros.add(miembro);
               
                miembro = new Miembros();
                miembro.setIdMiembro(1);
                miembro.setNombreMiembro("Germain");
                listaMiembros.add(miembro);

                formMiembros.setListaMiembros(listaMiembros);
        }

Cuando invoco al Action me direcciona al JSP en cuestión, como la lista esta vacía me pasa al "else" y me crea 2 registros, el Action me vuelve a direccionar al mismo JSP y los pinta, ahora que ya tengo esos registros los edito y vuelvo a invocar al Action, a la hora de obtener el tamaño de la lista, este es 0 por lo que me pasa al "else" y me crea los mismos registros, siendo que se modificaron desde el JSP.

Cabe mencionar que también probe de la siguiente manera:

JSP

<tr>
<logic:iterate name="MiembrosForm" property="listaMiembros" id="miembros" indexId="i">
        <td><html:text name='<%="miembros["+i+"]" %>' property="idMiembro" indexed="true"/></td>
        <td><html:text name='<%="miembros["+i+"]" %>' property="nombreMiembro" indexed="true"/></td>
        <td><html:file name='<%="miembros["+i+"]" %>' property="adjuntoUno" indexed="true"/></td>
        <td><html:file name='<%="miembros["+i+"]" %>' property="adjuntoDos" indexed="true"/></td>
</logic:iterate>
</tr>

FORM

        public ArrayList getListaMiembros() {
                return listaMiembros;
        }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }

        public Miembros getListaMiembro(int index) {
                return (Miembros)listaMiembros.get(index);
        }

        public void setListaMiembro(int index, Miembros miembro) {
                listaMiembros.set(index, miembro);
        }

En el Action es lo mismo, marca este error:

javax.servlet.ServletException: javax.servlet.jsp.JspException: Cannot find bean: "miembros[0]" in any scope

También probe esto solo en el JSP lo demas queda igual(FORM Y ACTION), solo le quite la propiedad indexed="true" a cada elemento

<tr>
<logic:iterate name="MiembrosForm" property="listaMiembros" id="miembros" indexId="i">
        <td><html:text name='<%="miembros["+i+"]" %>' property="idMiembro" /></td>
        <td><html:text name='<%="miembros["+i+"]" %>' property="nombreMiembro" /></td>
        <td><html:file name='<%="miembros["+i+"]" %>' property="adjuntoUno" /></td>
        <td><html:file name='<%="miembros["+i+"]" %>' property="adjuntoDos" /></td>
</logic:iterate>
</tr>

Me sale exactamente el mismo error de arriba.

Intente con este otro JSP, cambié la propiedad name por property dejando el valor anterior de name

<tr>
<logic:iterate name="MiembrosForm" property="listaMiembros" id="miembros" indexId="i">
        <td><html:text property='<%="miembros["+i+"]" %>' /></td>
        <td><html:text property='<%="miembros["+i+"]" %>' /></td>
        <td><html:file property='<%="miembros["+i+"]" %>' /></td>
        <td><html:file property='<%="miembros["+i+"]" %>' /></td>
</logic:iterate>
</tr>

Me sale este error:

javax.servlet.ServletException: javax.servlet.jsp.JspException: No getter method for property: "miembros[0]" of bean: "com.code.struts.forms.MiembrosPrincipalForm"

La verdad ya no se que intentar, espero y me den algún consejo. De antemano Gracias... Saludos.

Tu ejemplo original solo

Tu ejemplo original solo requiere unos cuantos cambios:

- El id y la propiedad deben llamarse igual
- El name de los elementos internos debe ser igual al valor de property del iterate
- Se debe utilizar la propiedad "indexed" con valor "true"

<logic:iterate id="listaMiembros" name="MiembrosForm" property="listaMiembros">
     <tr>
        <td><html:text name="listaMiembros" property="idMiembro" indexed="true"/>
        <td><html:text name="listaMiembros" property="nombreMiembro" indexed="true"/>
        <td><html:file name="listaMiembros" property="adjuntoUno" indexed="true"/>
        <td><html:file name="listaMiembros" property="adjuntoDos" indexed="true"/>
     </tr>
</logic:iterate>

Con esto el html generado será algo así

    <input type="text" name="listaMiembros[0].idMiembro value="..."/>
    <input type="
text" name="listaMiembros[0].nombreMiembro value="..."/>
    <input type="text" name="listaMiembros[0].adjuntoUno value="..."/>
    <input type="
text" name="listaMiembros[0].adjuntoDos value="..."/>
    <input type="text" name="listaMiembros[1].idMiembro value="..."/>
    ...
    <input type="
text" name="listaMiembros[n].idMiembro value="..."/>
    ...
Imagen de ghosttigger1203

Mmmmm creo que NO!!!

Mmmmmm creo que no queda así Neko Pui.

JSP

<logic:iterate id="listaMiembros" name="MiembrosForm" property="listaMiembros">
<tr>
        <td><html:text name="listaMiembros" property="idMiembro" indexed="true"/></td>
        <td><html:text name="listaMiembros" property="nombreMiembro" indexed="true"/></td>
        <td><html:file name="listaMiembros" property="adjuntoUno" indexed="true"/></td>
        <td><html:file name="listaMiembros" property="adjuntoDos" indexed="true"/></td>
</tr>
</logic:iterate>

FORM

         private ArrayList listaMiembros = new ArrayList();

         public ArrayList getListaMiembros() {
                return listaMiembros;
         }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }

ACTION

        ArrayList listaMiembros = formMiembros.getListaMiembros();
        Miembros m = new Miembros();
        if(listaMiembros.size() > 0){
                System.out.println("Iterando...");
                for(Object miembro : listaMiembros){
                        m = (Miembros)miembro;
                        System.out.println("ID miembro -> " + m.getIdMiembro());
                        System.out.println("Nombre miembro -> " + m.getNombreMiembro());
                        System.out.println("Adjunto 1 miembro -> " + m.getAdjuntoUno().getFileName());
                        System.out.println("Adjunto 2 miembro -> " + m.getAdjuntoDos().getFileName());
                       
                }
        }else {
                               
                System.out.println("Creando...");
                Miembros miembro = new Miembros();
                miembro.setIdMiembro(0);
                miembro.setNombreMiembro("Jonathan");
                listaMiembros.add(miembro);

                formMiembros.setListaMiembros(listaMiembros);
                               
        }

Me sale el siguiente error:

excepción

javax.servlet.ServletException: javax.servlet.ServletException: BeanUtils.populate

causa raíz

javax.servlet.ServletException: BeanUtils.populate

causa raíz

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

Cuando invoco al action la primera vez, se pasa al "else" lo cual pinta un registro en el JSP, al modificar éste e invocar de nuevo al action es cuando marca el error, parece que no se setea el registro en el ArrayList y al Iterarlo de nuevo en el JSP quiere tomar el primer elemento de la lista pero como la lista es de tamaño 0 por eso marca el error.

Espero sus comentarios y/o sugerencias chavos, Gracias!!!

Refiero al primer comentario

Faltan los métodos en tu form para recuperar el índice:

 
         private ArrayList listaMiembros = new ArrayList();

         public ArrayList getListaMiembros() {
                return listaMiembros;
         }

         public ArrayList getListaMiembros(int index) {
                ...
         }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }

        public void setListaMiembros(int index, ArrayList listaMiembros) {
                ...
        }

Con eso ahora sí debería funcionarte. Hace tiempo había un bug con Beanutils por el que no podías utilizar Listas, sino únicamente arreglos, pero me imagino que ese error ya no debe existir, así que con esos métodos adicionales todo debería funcionar.

Imagen de ghosttigger1203

Mmmmm ni con eso

Mmmmm ni con eso, de echo se me olvidó comentar que ya lo había probado de esa manera:

Con nombre de metodos para los index diferentes a los normales(solo le quite la "s").

        public ArrayList getListaMiembros() {
                return listaMiembros;
        }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }
       
        public Miembros getListaMiembro(int index) {
                return (Miembros)listaMiembros.get(index);
        }

        public void setListaMiembro(int index, Miembros miembro) {
                listaMiembros.set(index, miembro);
        }

Me da el siguiente error:

excepción

javax.servlet.ServletException: javax.servlet.ServletException: BeanUtils.populate

causa raíz

javax.servlet.ServletException: BeanUtils.populate

causa raíz

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
java.util.ArrayList.RangeCheck(ArrayList.java:547)
        java.util.ArrayList.get(ArrayList.java:322)
        org.apache.commons.beanutils.PropertyUtilsBean.getIndexedProperty(PropertyUtilsBean.java:433)
        org.apache.commons.beanutils.PropertyUtilsBean.getIndexedProperty(PropertyUtilsBean.java:340)
        org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:684)
        org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:715)
        org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:884)
        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:467)
        org.apache.struts.chain.commands.servlet.PopulateActionForm.populate(PopulateActionForm.java:50)
        org.apache.struts.chain.commands.AbstractPopulateActionForm.execute(AbstractPopulateActionForm.java:60)
        org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
        org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
        org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
        org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
        org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
        org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
        org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Con nombres iguales tanto para getters y setters(le deje la "s")

        public ArrayList getListaMiembros() {
                return listaMiembros;
        }

        public void setListaMiembros(ArrayList listaMiembros) {
                this.listaMiembros = listaMiembros;
        }
       
        public Miembros getListaMiembros(int index) {
                return (Miembros)listaMiembros.get(index);
        }

        public void setListaMiembros(int index, Miembros miembro) {
                listaMiembros.set(index, miembro);
        }

Me da el siguiente error al cargar de inicio el JSP

excepción

org.apache.jasper.JasperException: javax.servlet.ServletException: org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspException: No getter method for property: "listaMiembros" of bean: "MiembrosForm"

causa raíz

javax.servlet.ServletException: javax.servlet.jsp.JspException: No getter method for property: "listaMiembros" of bean: "MiembrosForm"

Espero sugerencias porfa, no se que sea :(.

Saludos!!!

Ya intentaste con arrays?

Recuerdo que había un error en java 1.4 con el que sucedía eso. Intenta utilizar arreglos en vez de listas a ver si te funciona. La otra solución, que era muy engorrosa por cierto, era utilizar DynaBeans. Prueba cambiarlos a Miembros[].
Si esto de plano no funciona... que Dios nos agarre confesados, jeje. Quiero decir, ya no puedo ayudarte mucho.

Ejemplo con lista que contiene listas

¡Solucionado!

el ejemplo lo hice con una lista de personas en donde cada una tiene un nombre y una lista de facturas y las facturas cada una tiene un valor y una cantidad

así

public class Persona
{
        private String nombre;
        private List<Factura> facturas;
       
        public Persona(String nombre, List<Factura> facturas){
                this.nombre = nombre;
                this.facturas = facturas;
        }
        public String getNombre() {
                return nombre;
        }
        public void setNombre(String nombre) {
                this.nombre = nombre;
        }
        public List<Factura> getFacturas() {
                return facturas;
        }
        public void setFacturas(List<Factura> facturas) {
                this.facturas = facturas;
        }
}

public class Factura
{
        private Integer cantidad;
        private Integer valor;
       
        public Factura(Integer cantidad, Integer valor){
                this.cantidad = cantidad;
                this.valor = valor;
        }
        public Integer getCantidad() {
                return cantidad;
        }
        public void setCantidad(Integer cantidad) {
                this.cantidad = cantidad;
        }
        public Integer getValor() {
                return valor;
        }
        public void setValor(Integer valor) {
                this.valor = valor;
        }
}

public class formaPersonas
{
        private List<Persona> personas;

        //inicializacion
        {
                if(personas == null)
                {
                        personas = new ArrayList<Persona>();
                        ArrayList<Factura> facturas1 = new ArrayList<Factura>();
                        facturas1.add(new Factura(1, 1000));
                        facturas1.add(new Factura(2, 2000));
                        personas.add(new Persona("juan", facturas1));
                       
                        ArrayList<Factura> facturas2 = new ArrayList<Factura>();
                        facturas2.add(new Factura(3, 3000));
                        facturas2.add(new Factura(4, 4000));
                        personas.add(new Persona("camilo", facturas2));
                }
        }
       
        public List<Persona> getPersonas() {
                return personas;
        }
        public void setPersonas(List<Persona> personas) {
                this.personas = personas;
        }
}

en la página iría así

<%String nombreForma = "formaPersonas";%>
<table>
 <logic:iterate name="<%=nombreForma%>" property="personas" id="personas" type="com.edu.Persona" indexId="i">
  <tr>
   <td>
    <html:text name="<%=nombreForma%>" property="<%="personas["+i+"].nombre"%>"></html:text>
   </td>
   <td>
    <table>
     <logic:iterate name="personas" property="facturas" id="facturas" type="com.edu.Factura" indexId="j">
      <tr>
       <td>
        <html:text name="<%=nombreForma%>" property="<%="personas["+i+"].facturas["+j+"].cantidad"%>"></html:text>
       </td>
       <td>
        <html:text name="<%=nombreForma%>" property="<%="personas["+i+"].facturas["+j+"].valor"%>"></html:text>
       </td>
      </tr>
     </logic:iterate>
    </table>
   </td>
  </tr>
 </logic:iterate>
</table>

sí se hacen cambios en los campos de texto, al hacer submit se habrán guardado todos los datos correctamente en el form en el objeto List<Persona> personas;

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">