2

My question is: how to give dynamic param to an url using <s:itarator> in struts2? I have some data stored in a MySQL database, I put the data (Id and Name) in two ArrayList

    package Model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class Film {
    private String id;
    private String titolo;
    private String trama;
    private int i=0;
    private ArrayList<String> puntate = new ArrayList<String>();
    private ArrayList<Integer> idPuntate = new ArrayList<Integer>();
    protected String DRIVER = "com.mysql.jdbc.Driver";
    protected String url = "jdbc:mysql://localhost/SitoWeb";
    protected String user = "root";
    protected String psw = "";
    private Connection con;
    public String execute(){
    Connessione();
    Query();
    return "success";
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    public String getId() {return id;}
    public void setId(String id) {this.id = id;}
    public String getTitolo(){return titolo;}
    public void setTitolo(String titolo)  {this.titolo=titolo;}
    public String getTrama(){return trama;}

    public void Connessione(){
        try{
        con=null;
        Class.forName(DRIVER);
        con = DriverManager.getConnection(url,user,psw);
        }catch(Exception e){}
    }   
    public void Query(){
        try {
            PreparedStatement cmd = con.prepareStatement("SELECT Film.Titolo, Film.Trama, Episodi.Nome, Episodi.idEpisodio FROM Film INNER JOIN Episodi ON Film.Id = Episodi.id_Film WHERE id = ?");
            cmd.setString(1, id);
            ResultSet rs = cmd.executeQuery();
            while(rs.next()){
                titolo = rs.getString("titolo");
                trama = rs.getString("trama");
                idPuntate.add(i, rs.getInt("idEpisodio"));
                puntate.add(i,rs.getString("Nome"));
                i++;
            }
            rs.close();
            cmd.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public ArrayList<Integer> getIdPuntate() {
        return idPuntate;
    }

    public void setIdPuntate(ArrayList<Integer> idPuntate) {
        this.idPuntate = idPuntate;
    }

    public ArrayList<String> getPuntate() {
        return puntate;
    }

    public void setPuntate(ArrayList<String> puntate) {
        this.puntate = puntate;
    }
}

Now I want to show these data in my JSP page. I tried something like this:

<s:url action="episodi" var="episodi">
<s:param name="id"></s:param> // I don't know what to put here...
</s:url>
<ol>
<s:iterator value="puntate">
  <li><a href="<s:property value='#episodi'/>"><s:property/></a></li>
</s:iterator>
</ol>

I don't know what to put in <s:param name="id"></s:param> because the param is an ArrayList. I tried to put <s:iterator value="idPuntate"> but it returns 0..

Renny
  • 114
  • 10

1 Answers1

2

There are two problems:

  1. If you are generating an url for each element of a Collection, then you need to put the url generation inside the iteration of that Collection, otherwise you will have always the same url:

    <ol>
    <s:iterator value="puntate">
        <s:url action="episodi" var="episodio">
            <s:param name="id">something here</s:param>
        </s:url>
    
        <li><a href="<s:property value='#episodio'/>"><s:property/></a></li>
    </s:iterator>
    </ol>
    
  2. You have not used OOP, that would suggest to create a bean named Movie (or Film), with a List<Episode>, and Episode should be another bean with for example Long id, Integer season, Integer number, and String description.

    Since you've used two different lists, one for the episode description and another one for the episode id, and assuming they're aligned (it is not guaranteed, so I strongly suggest you to refactor your code the OOP way), you can access the IDs by their index basing on the episode description index, during the iteration:

    <ol>
    <s:iterator value="puntate" status="ctr">
        <s:url action="episodi" var="episodio">
            <s:param name="id">
                <s:property value="idPuntate[%{#ctr.index}]"/>
            </s:param>
        </s:url>
    
        <li><a href="<s:property value='#episodio'/>"><s:property/></a></li>
    </s:iterator>
    </ol>
    

P.S: Film should be a bean declared in your action, not the action itself... otherwise it is not portable... what if you need the Film class in other actions ?

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Can you explain this `idPuntate[%{#ctr.index}]` ? And why my Film class is not portable? – Renny Jan 12 '15 at 16:16
  • Sure, [read this](http://stackoverflow.com/a/27245891/1654265) and the other answer in the same question that is quoting the documentation. It is not portable because it is an action... it should be a single bean, and an action should not be ported into other files... – Andrea Ligios Jan 12 '15 at 16:38
  • I'm confused.. can you link me something to unserstand what I have to do to not use Film as action? And for the OOP thing, I have to create a bean called Episode, with Long id, integer season etc (as you said), then in my class called Film I put data into variables with getter and setter and then? How can I show it on JSP page? Sorry if I'm asking too many things, but I'm still learning.. :S – Renny Jan 12 '15 at 16:52
  • Create Episode with its attributes and getters/setters. Create Film or Serie with its attributes, including a List and getters/setters. then in action use `private Film film; // getter & setter public String execute(){ film = loadFilmInSomeWay(); return SUCCESS; }` and in JSP with dot `.` notation: ``. – Andrea Ligios Jan 12 '15 at 16:56
  • This will help a lot I guess: http://stackoverflow.com/a/15009137/1654265. This might help too: http://stackoverflow.com/a/13837913/1654265 – Andrea Ligios Jan 12 '15 at 16:58
  • Just one last thing. I think that I don't know what is an action. Exactly, I don't know how to create an action.. I thought it was something like this `public class Name extends ActionSupport` but it seems that it is not this.. – Renny Jan 12 '15 at 17:36
  • :D It is that instead. You are just misinterpreting what purposes should it serve... it is the presentation layer, the "bridge" between the business layer (where the data is loaded from database or webservices, manipulated, etc) and the view (where the data is read/written by the user). Nothing is preventing you to load the data directly in the action, especially if it is a project for yourself... but an action is threadsafe, runs through an interceptor stack, it's a lot of things, but it's *not* a bean to pass to other classes – Andrea Ligios Jan 12 '15 at 17:42