Verschachtelte for-Schleifen mit JSP oder Struts?

Hallo zusammen,

kann mir zufällig jemand dabei helfen, eine verschachtelte for-Schleife wie die unten aufgeführte in JSP- oder Struts-Syntax zu übersetzen, so dass ich keinen unnötigen Java-Code auf meiner JSP-Seite habe?

ArrayList array = new ArrayList(collection1);
ArrayList array2 = new ArrayList(collection2);

for(int i = 0; i < array.size(); i++){
out.println(array.get(i));
if(array.get(i) == value_from_request){
for(int j = 0; j < array2.size(); j++){
out.println(array2.get(j));
}
}
}

Struts bietet ja das <iterate>-Tag an, das aber bei Verschachtelung nicht zu funktionieren scheint.

Ich bin für jede Hilfe dankbar! Schöne Grüße,
Peter
 
Hallo!

Klar funktioniert logic:iterate bei Verschachtelungen, du scheinst nicht genügend ausprobiert zu haben.

Code:
<logic:present name="array1">
  <logic:present name="array2">
    <logic:iterate name="array1" id="a1">
      <bean:write name="a1" />
      <bean:define name="valueFromRequest" id="valFromReq" />
      <logic:equal name="a1" value="<%=(String) valFromReq%>">
        <logic:iterate name="array2" id="a2">
          <bean:write name="a2" />
        </logic:iterate>
      </logic:equal>
    </logic:iterate>
  </logic:present>
</logic:present>
Solange dein "valueFromRequest" keine Konstante ist, wirst du um den Ausdruck "<%=(String) valFromReq%>" nicht herumkommen.

Grüsse TrueSun
 
Hi TrueSun,

vielen Dank erstmal für deine Hilfe!
Nur leider funktioniert es immer noch nicht, und ich versuche nun schon 2 Stunden den Fehler zu finden. Vielleicht kannst du mir nochmal helfen ...

Ich habe unten mal meinen Code angefügt. Mein Ziel ist es, dass zum einen alle Bestände und zum anderen zu einem vom Benutzer jeweils vorher ausgewählten Bestand alle Perioden ausgeben werden. Die Bestände werden auch brav ausgegeben, aber es kommt zu keiner Ausgabe der Perioden.
Das Problem liegt scheinbar schon beim <logic:equal>-Tag, da auch kein normaler Text innerhalb von dessen Body ausgegeben wird.
Kann es sein, dass es Probleme gibt, weil die Bestandsnamen Zahlenwerte sind und sie dann intern in Integer umgewandelt werden? Allerdings ist selectedBestand auch ein Zahlenwert, so dass da ja gleiches gelten müsste.

Ich bin echt am Verzweifeln! Es wäre echt toll, wenn du (oder jemand anders) eine Idee hätte!

mein Code:

<logic:iterate name="bestaende" id="bestand">
<bean:write name="bestand" property=bestand />
<bean:define name="selectedBestand" id="selectedBestand" />
<logic:equal name="bestand" value="selectedBestand">
<logic:iterate name="perioden" id="periode">
<bean:write name="periode" property="periode" />
</logic:iterate>
</logic:equal>
</logic:iterate>
 
Hallo!

Die Bedeutung einiger Parameter in Strutstags ist öfters nicht selbsterklärend und man muss in vielen Fällen nochmal in die Doku reinschauen.
Z.B. wird der Parameter "value" im logic:equal-tag als konstanter ausdruck gewertet. Du vergleichst also den Inhalt eines Beans mit einer Zeichenkette, z.B. die Zahl 124 als Wert des Beans "bestand", verglichen mit der Zeichenkette "selectedBestand" und nicht mit dem Wert eines beans mit namen "selectedBestand". Da das Feld value aber laut doku ein Laufzeitausdruck (RT expr) ist, kannst du mittels <%=(String) valFromReq%> an dieser Stelle doch ein bean auswerten. Probier also mal folgendes:

Code:
<logic:iterate name="bestaende" id="bestand">
  <bean:write name="bestand" property=bestand />
  <bean:define name="selectedBestand" id="selBestand" />
  <logic:equal name="bestand" value="<%=(String) selBestand%>">
    <logic:iterate name="perioden" id="periode">
      <bean:write name="periode" property="periode" />
    </logic:iterate>
  </logic:equal>
</logic:iterate>

Noch etwas, wenn du folgendes schreibst:
<bean:write name="periode" property="periode" />
dann hat das bean "periode" also noch ein Feld das "periode" heisst, das ist unwahrscheinlich. Ich glaube vielmehr, dass du eine bean periode hast, dass direkt einen Wert enthält. In diesem Fall musst du den parameter "property" weglassen.

Grüsse TrueSun
 
Hallo TrueSun,

nochmal vielen Dank für deine Hilfe, aber wieder hat es leider nicht funktioniert.

Bei der Nutzung deines Codes wird eine ClassCast-Exception geschmissen. Ich vermute ja, dass es irgendwie mit den Beständenamen zu tun hat, die ja Zahlenwerte sind und scheinbar irgendwie intern in Integer umgewandelt werden.

Hast du eine Idee, was man da machen kann?

Und noch eine ganz blöde Frage:
Du schreibst, ich solle bei der Ausgabe der Perioden nicht auch noch den Wert "property" mit angeben. Ich fürchte, das hängt mit meiner (wohl falschen) Vorstellung davon zusammen, wie Daten zwischen dem Servlet und der JSP ausgetauscht werden, d.h.mit meiner Vorstellung von einer Bean.
Ich habe jetzt für jeden Datentyp, auf den aus einer JSP zugegriffen wird, eine eigene Klasse kreiert.

z.B. für Perioden-Elemente die Klasse:

public class Periode{

protected String periode;

public void setPeriode(String periode){
this.periode = periode;
}

public String getPeriode(){
return periode;
}
}



Eine ArrayList mit Instanzen dieser Klasse habe ich dann per request.setAttribute("perioden",perioden_arrayList) für die JSP verfügbar gemacht.
Ist das Blödsinn? Wie macht man das richtig?

Nochmals vielen Dank für deine Geduld und schöne Grüße,
Peter
 
Hey!

Ok, wenn das bean ein Integer enthält, dann ist der cast natürlich falsch
<%=((Integer) selBestand).toString()%> wird dann hoffentlich funktionieren.

Zu den beans, unter dem Gesichtspunkt der Erweiterbarkeit, also wenn die Klasse Periode noch wachsen könnte, dann ist das so wie du es gemacht hast ganz in Ordnung. Wobei ein Feld einer Klasse nicht wie die Klasse selbst heissen sollte.
Wenn du allerdings bloss eine Menge von Strings übergeben willst, dann brauchst du natürlich keine extra Klasse dafür.
Du kannst dann das String-Array oder eine Arraylist mit Strings direkt in Request oder Session speichern.
Ich war mir nur nicht sicher ob du den Unterscheid zischen "name" und "property" verstanden hast, sry :)

Grüsse TrueSun
 
Hallo TrueSun,

vielen Dank nochmal, aber leider kann ich immer noch keine Erfolgsmeldung machen.

Leider gibt es weiterhin eine ClassCastException. Habe dann auch nochmal ausprobiert, die Namen der Bestände in Strings zu verändern, aber obwohl dann nur noch Strings im Spiel sind, gab es eine ClassCastException bei dem Aufruf

<bean:define name="selectedBestand" id="selBestand" />
<logic:equal name="bestand" value="<%=(String)selBestand%>">

Ich glaube ich gebe es auf mit dem verschachtelten <iterate>-Tag... Oder hast du noch eine Idee?

Auf jeden Fall nochmals Dank für die Mühe,
Peter

Eins fällt mir gerade noch ein: Könnte das Problem sein, dass ich wie bei den Perioden auch für die Bestände eine Klasse Bestand angelegt habe, die ähnlich aussieht wie die Klasse Periode, nur dass sie noch über zusätzliche Attribute verfügt, die ebenfalls über das Property-Attribut in der ersten Schleife ausgegeben werden. (deshalb benutze ich das Property-Tag, über das du dich gewundert hast...)

Die Klasse Bestand:
public class Bestand{

protected String bestand;
protected String hasPeriode;

public void setBestand(String bestand){
this.bestand= bestand;
}

public String getBestand(){
return bestand;
}

public void setHasPeriode(String hasPeriode){
this.hasPeriode= hasPeriode;
}

public String getHasPeriode(){
return hasPeriode;
}
...
}
Das Problem könnte demnach sein, dass die Angabe name="bestand" im <logic:equal>-Tag nicht ausreicht, weil sozusagen, die Property (hier: nochmal "bestand" fehlt ...). Kann das sein? Und was könnte ich tun?

Viele Grüße ...
 
Hi!
War übers WE weg, sry :)

<bean:define name="selectedBestand" id="selBestand" />

Damit wird ein Bean "selBestand" mit dem Wert des Beans "selectedBestand" erzeugt. Wenn das Bean "selectedBestand" keinen Wert, sondern eine Property "bestand" hat, dann muss die Zeile folgendermassen lauten

<bean:define name="selectedBestand" id="selBestand" property="bestand" />

wie du ja auch schon selbst herausgefunden hast.

Grüsse TrueSun
 
Hi,
kaum zu glauben aber wahr - jetzt läufts! Vielen, vielen DAnk. Das Problem war wie es aussieht die ganze Zeit mein scheinbar nicht ganz korrekter Umgang mit JavaBeans, der immer noch das property-Attribut verlangte.

(Muss man nur eine einzige Bean schreiben, die alle Attribute enthält, d.h. in diesem Fall eine ArrayList für die Bestände und eine für die Perioden, sowie ein Attribut selectedBestand? Ich habe dafür nämlich drei Beans definiert ...)

Habe zusätzlich noch in der Zeile

<logic:equal name="bestand" value="<%=(String)selBestand%>">

property="bestand"

eingefügt und dann gings! Olé!

Danke für die Geduld,
Peter
 
Zuletzt bearbeitet:
Freut mich, dass es jetzt läuft!

Zu den Beans:
Wenn die von dir aufgezählten Beans immer gemeinsam auftreten, also kontextmässig zusammenhängen, dann macht es durchaus Sinn, daraus ein einziges Bean zu bauen. Brauchst du allerdings manchmal nur ein Teil des Beans, dann wäre es günstiger, mehrere Beans zu haben.
Eine weitere Überlegung ist der Speicherort des Beans. Wird das Bean einmalig, z.B. zur Anzeige, gebraucht, dann wäre es sinnvoll, das Bean im Request zu speichern, da es in der Session sonst weiterhin mitgeschleppt wird. In der Session machen nur Sitzungsübergreifende Daten Sinn.

Grüsse TrueSun
 
Zurück