Aufruf einer Methode mit parameter innerhalb JSTL-Schleife
Ich habe eine JSP, die muss zum drucken text, das hergestellt wird, indem die loop-iterator und Einspeisung zu einem anderen Objekt (Spring bean), so etwas wie:
<c:forEach var="myVar" items="${myVars}">
<c:out value="anotherObject.getFoo(myVar)"/>
</c:forEach>
Offensichtlich der obige code ist nicht gültig als JSTL .
Betreiber nur erlaubt parameter-weniger Aufrufe. Ich sehe folgende Lösungen für das problem:
1) Scriptlets
<c:forEach var="myVar" items="${myVars}">
<%
SomeType myVar = (SomeType) pageContext.getAttribute("myVar");
SomeOtherType anotherObject = (SomeOtherType) pageContext.getAttribute("anotherObject");
YetAnotherType result = anotherObject.getFoo(myVar);
pageContext.setAttribute("result", result);
%>
<c:out value="${result}"/>
</c:forEach>
Die offensichtliche con hier ist JSP-code Verschmutzung und Allgemeine Hässlichkeit.
2) Schreiben von einem tag, das tut, was auch immer geschieht innerhalb von scriptlets. Typisches Beispiel für over-engineering, igitt!
3) Zerlegen Sie eine Sammlung von myVars
und ersetzen Sie jedes myVar
mit einem dynamische proxy, InvocationHandler
würde, die zusätzliche parameter-weniger-Methode, um alle getFoo()
Anrufe über anotherObject
. All das geschieht in den controller so JSP würden sauber bleiben und myVar
bleibt die gleiche. Aber zu welchem Preis?
Kann ich nicht hinzufügen .getFoo()
Methode, um die myVar
weil es nicht passt und es würde brechen, die Trennung von Bedenken.
Sieht es aus wie die übergabe von Parametern möglich sein wird in JSP/EL 2.2, aber ich bin mit Tomcat 6.0.29, die nur die bundles EL 2.1 API.
Frage: kann jeder jeden schlagen der sauberste Ansatz für diese situation?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer einfachen Java-only "- trick-Update", das funktioniert in der älteren JSTL-version, auch
und erfordert keinen zusätzlichen taglibs/config/Abhängigkeiten/Rahmenbedingungen, etc.
ist "wrap" die Funktion, die Sie aufrufen möchten JSTL
in einer Klasse erstreckt sich von einem
Map
- Klasse und überschreiben Sie dieget()
Methode.Als ein minimal-Beispiel, wenn Sie z.B. möchten, rufen Sie die
Math.sin()
Funktion von JSTL,definieren Sie eine Klasse:
Dann in Ihrer Aktion execute () - Methode, die Sie tun:
Dann in jsp kann man sagen:
berechnen Sie den Wert
Math.sin(0.75)
JSTL zu behandeln, wird die variable Sinus als
Map
, aber man kann berechnen und zurückgeben, was Sie wollen aus der get () - Methode.Ich denke, es wird ein bisschen mehr beteiligt, wenn Sie mehr als ein argument, um Ihre Funktion,
aber es sollte Problemumgehungen für die das auch 🙂
Hier ist, wie ich es getan habe am Ende.
Statt der übergabe einer Sammlung von
SomeType
Instanzen, leite ich eine Karte. Map-keys sind die gleichenSomeType
s und die Werte sind Instanzen der controller-spezifische innere Klasse, nennen wir esSomeTypeSupplement
.SomeTypeSupplement
sorgt für die nötige no-arg-get-und-Drähte alles zusammen. JSP nun iteriert über die map-Einträge und ist in der Lage, zum abrufen der Daten via JSTL.Diese Weise vermeide ich
Proxy
Magie, unnötige TLDs, halten JSPs ordentlich und vernünftig Typ-sicher.Wenn Sie nicht halten mit scriptlets (deine Variante 1), würde ich erstellen Sie eine benutzerdefinierte Tags, die für Sie (Ihre alternative 2) oder eine benutzerdefinierte EL-Funktion. Ich bin nicht einverstanden, dass es "over-engineering", es ist mit den verfügbaren tools für den beabsichtigten Zweck.
Ihre alternative 3, allerdings, mag ich nicht. Wenn überhaupt, IST DAS over-engineering plus es wird Ihr system unnötig Komplex und schwieriger für andere Menschen zu Folgen. Befolgen Sie die Absichten der Spezifikationen und standards, die Sie arbeiten in. Machen es nicht schwerer oder komplexer als Selbstzweck.
anotherObject
") und erfordert dieses Modell Klasse. Ihren Vorschlag, sich zu bewegen-Logik für Controller-Schicht ist in der Nähe auf option #3, die ich vorgeschlagen und Sie sagte, es war eine schlechte Idee.Warum nicht, stellen Sie einfach Ihre Objektliste im backend von Java-code und dann nur mit JSP anzuzeigen?
${myVars}
bereits bezieht sich auf eine Liste von Objekten.Wollte, um einen Kommentar hinzuzufügen, um die last (durch die Zeit) die Antwort von Rop, aber es fehlte der "Ruf", also hier bin ich mit einer Antwort.
Ich kurz hatte die gleiche Idee mit so einer Karte, aber versucht es allgemein verwendbar, mit einem "DynamicMap", DynamicMapCalculator-Schnittstelle, und lassen Sie wickeln jeden Methodenaufruf in eine solche Karte (ohne eine neue Karte die Umsetzung jedes mal, nur unter Verwendung der anonymen Klasse Instanziierung).
Dies wäre das Thema, wenn Sie interessiert sind:
Eine qu. der Stil: dynamische Karte JSTL hack zu arbeiten, um fehlende parameter Funktion ruft
Und ich wäre interessiert an Meinungen gibt: ist das etwas, was Sie tun können, ohne ein schlechtes gewissen?
Andere Möglichkeit ist die Verwendung Geschwindigkeit. Es ist viel schöner, als jstl.