Wie vermeide ich die Verwendung von Skriptlets auf meiner JSP-Seite?

Lesezeit: 9 Minuten

Mir wurde gesagt, dass die Verwendung von Skriptlets (<%= ... %>) in meinen JSP-Seiten keine so gute Idee ist.

Kann mir bitte jemand mit etwas mehr Java/JSP-Erfahrung einige Hinweise geben, wie ich diesen Code ändern kann, damit er mehr “Best Practice” ist, was auch immer das sein mag?

Diese JSP ist eigentlich meine Haupt-Decorator-Seite für das Sitemesh. Grundsätzlich hat mein Webdesign eine Registerkartenleiste und ein Untermenü, und ich möchte die aktuelle Registerkarte irgendwie hervorheben und das richtige Untermenü anzeigen, indem ich mir den aktuellen Anforderungs-URI ansehe.

<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>

<html>
<head>
  <title>My Events - <decorator:title /></title>
  <link href="https://stackoverflow.com/questions/2188706/<%=%20request.getContextPath()%20%>/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>

<div class="tabs">
  <a 
    <%= request.getRequestURI().contains("/events/") ? "class="selected"" : "" %>
    href="<%=%20request.getContextPath()%20%>/events/Listing.action">Events</a>
  <a 
    <%= request.getRequestURI().contains("/people/") ? "class="selected"" : "" %>
    href="<%=%20request.getContextPath()%20%>/people/Listing.action">People</a>
</div>

<div class="submenu">
  <% if(request.getRequestURI().contains("/events/")) { %>
    <a href="Listing.action">List of Events</a>
    |<a href="New.action">New Event</a>
  <% } %>
  <% if(request.getRequestURI().contains("/people/")) { %>
    <a href="Listing.action">List of People</a>
    |<a href="New.action">New Person</a>
  <% } %>  
  &nbsp;
</div>

<div class="body">
  <decorator:body />
</div>

</body>
</html>

Danke an alle

  • Abgesehen davon, ist ‘<%= request.getContextPath() %>‘ eine akzeptable Verwendung von Skriptlets, die nicht so sehr verpönt ist?

    – Chris

    3. Februar 10 um 0:00 Uhr

  • Sie sollten damit beginnen, Facelets für die Vorlagenerstellung zu verwenden. Zwingt Sie, richtig zu codieren.

    – Andreas Dyster

    3. Feb. 10 um 0:02

  • Wollen Sie Facelets anstelle von Sitemesh verwenden?

    – Chris

    3. Februar 10 um 0:13 Uhr

  • mögliches Duplikat von stackoverflow.com/questions/3177733/…

    – Bozo

    20. Oktober 10 um 22:16 Uhr

Wie vermeide ich die Verwendung von Skriptlets auf meiner JSP Seite
BalusC

Ich denke, es hilft mehr, wenn Sie mit eigenen Augen sehen, dass es tatsächlich vollständig gemacht werden kann ohne Skripte.

Hier ist eine 1-zu-1-Umschreibung mit Hilfe von unter anderem JSTL (einfach fallen lassen jstl-1.2.jar in /WEB-INF/lib) Ader und Funktionen taglib:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<html>
<head>
  <title>My Events - <decorator:title /></title>
  <link href="https://stackoverflow.com/questions/2188706/${pageContext.request.contextPath}/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>

<div class="tabs">
  <a 
    ${fn:contains(pageContext.request.requestURI, '/events/') ? 'class="selected"' : ''}
    href="${pageContext.request.contextPath}/events/Listing.action">Events</a>
  <a 
    ${fn:contains(pageContext.request.requestURI, '/people/') ? 'class="selected"' : ''}
    href="${pageContext.request.contextPath}/people/Listing.action">People</a>
</div>

<div class="submenu">
  <c:if test="${fn:contains(pageContext.request.requestURI, '/events/')}">
    <a href="Listing.action">List of Events</a>
    |<a href="New.action">New Event</a>
  </c:if>
  <c:if test="${fn:contains(pageContext.request.requestURI, '/people/')}">
    <a href="Listing.action">List of People</a>
    |<a href="New.action">New Person</a>
  </c:if>
  &nbsp;
</div>

Hier ist eine optimierte Umschreibung, beachten Sie, dass ich verwendet habe c:set Ausdrucksergebnisse für die Wiederverwendung “zwischenzuspeichern” und dass ich HTML verwende <base> -Tag, um zu vermeiden, dass der Kontextpfad in jeden Link eingefügt wird (machen Sie einfach alle relativen URLs auf Ihrer Webseite relativ dazu – ohne den führenden Schrägstrich!):

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<c:set var="isEvents" value="${fn:contains(pageContext.request.requestURI, '/events/')}" />
<c:set var="isPeople" value="${fn:contains(pageContext.request.requestURI, '/people/')}" />

<html>
<head>
  <title>My Events - <decorator:title /></title>
  <base href="https://stackoverflow.com/questions/2188706/${pageContext.request.contextPath}">
  <link href="assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>

<div class="tabs">
  <a ${isEvents ? 'class="selected"' : ''} href="events/Listing.action">Events</a>
  <a ${isPeople ? 'class="selected"' : ''} href="people/Listing.action">People</a>
</div>

<div class="submenu">
  <c:if test="${isEvents}">
    <a href="Listing.action">List of Events</a>|<a href="New.action">New Event</a>
  </c:if>
  <c:if test="${isPeople}">
    <a href="Listing.action">List of People</a>|<a href="New.action">New Person</a>
  </c:if>
  &nbsp;
</div>

Es kann tatsächlich mehr optimiert werden, wenn Sie all diese “fest codierten” Werte wie sammeln events und people und Linktexte in a Map im Anwendungsbereich und Verwendung unter jeder der JSTL <c:forEach> um die Registerkarten anzuzeigen.

Was deine betrifft tatsächlich Frage, du kannst deaktivieren scriptlets (und erhalten Laufzeitfehler bei der Verwendung), indem Sie den folgenden Eintrag in webapp’s hinzufügen web.xml. Es kann hilfreich sein, übersehene Skriptlets zu erkennen.

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <scripting-invalid>true</scripting-invalid>
    </jsp-property-group>
</jsp-config>

Um mehr über EL zu erfahren, besuchen Sie die Java EE-Lernprogramm Teil II Kapitel 5. Implizite EL-Objekte, wie z ${pageContext} sind beschrieben Hier. Um mehr über JSTL zu erfahren, überprüfen Sie die Java-EE-Lernprogramm Teil II Kapitel 7. Beachten Sie, dass JSTL und EL zwei verschiedene Dinge sind. JSTL ist ein Standard-Taglib und EL ermöglicht nur den programmgesteuerten Zugriff auf Backend-Daten. Obwohl es normalerweise in Taglibs wie JSTL verwendet wird, kann es auch eigenständig in Vorlagentext verwendet werden.

  • Wenn Sie die „Vorher“- und „Nachher“-Vorlagen vergleichen, werden Sie feststellen, dass sie ziemlich gleich sind. Ich sehe nicht, wie letzteres automatisch besser ist als ersteres (außer dass es ein bisschen sauberer aussieht).

    – Ree

    14. Juli 10 um 20:53 Uhr

  • @Ree – Ehrlich gesagt denke ich, dass der größte Vorteil von JSTL darin besteht, dass es Ihnen nicht die Freiheit gibt, beliebigen Code in Ihrer JSP zu schreiben. JSTL bietet Ihnen fast alle Tools, die Sie zum Schreiben von Vorlagen benötigen, nicht Controller, Geschäftslogikmanager oder Datenzugriffsobjekte.

    – RustyTheBoyRobot

    7. Juni 12 um 23:44 Uhr

Wie vermeide ich die Verwendung von Skriptlets auf meiner JSP Seite
Thilo

Nebenbei ist <%= request.getContextPath() %> ein akzeptabler einsatz von scriptlets, der nicht so verpönt ist?

Dies mag eine unpopuläre Meinung sein, aber wenn Sie nur einfache Bedingungen und Texteinfügungen tun, kann ich an der Verwendung von Skriptlets nicht viel aussetzen. (Beachten Sie das wenn)

Ich würde wahrscheinlich JSTL und die Ausdruckssprache verwenden, aber hauptsächlich, weil es weniger Tipparbeit erfordern kann und die IDE-Unterstützung möglicherweise besser ist (aber eine gute JSP-IDE kann auch fehlende schließende Klammern und ähnliches finden).

Aber grundsätzlich (wie in “Logik aus Vorlagen heraushalten”) sehe ich keinen Unterschied zwischen

<% if(request.getRequestURI().contains("/events/")) { %>

und

${fn:contains(pageContext.request.requestURI, '/events/') 

  • Okay toll! Ich dachte ich wäre der einzige mit dieser Meinung!

    – Chris

    3. Februar 10 um 2:34 Uhr

  • Ich denke, der Kontext hier ist einer der besten Praktiken, der mehr ins Spiel kommt, wenn Sie nicht der Einzige sind, der eine Vorlage entwickelt oder pflegt. Obwohl es in Ihrem Beispiel funktional keinen Unterschied gibt, haben Sie die Verwendung von Skriptlets priorisiert, und jemand, der es nicht besser weiß, kann beliebigen Java-Code einfügen, der den Zustand eines Modells ändert. Nur etwas zu bedenken. Ich mag die Idee, sie als oben erwähntes BalusC zu deaktivieren.

    – Cole Stanfield

    26. November 12 um 23:45 Uhr

Skriptlets sind nicht das Schlimmste auf der Welt. Eine wichtige Überlegung ist, darüber nachzudenken, wer den Code pflegen wird. Wenn es sich um Webdesigner handelt, die nicht viel Java-Erfahrung haben, sind Sie wahrscheinlich besser dran, wenn Sie Tag-Bibliotheken verwenden. Wenn Java-Entwickler jedoch die Wartung übernehmen, ist es für sie möglicherweise einfacher, Skriptlets zu verwenden.

Wenn Sie am Ende eine Tag-Bibliothek und JSTL verwenden, erwarten Sie, dass der Betreuer auch die Tag-Bibliothek lernt und JSTL kennt. Einige Entwickler werden damit einverstanden sein, da es eine Fähigkeit ist, die sie wollen oder bereits haben, aber für einige Entwickler, die sich nur etwa alle paar Monate mit JSPs befassen müssen, kann es viel weniger schmerzhaft sein, mit klar geschriebenen Skriptlets zu arbeiten, die in nett geschrieben sind , bekanntes Java.

Dies ist keine direkte Antwort auf Ihre Frage (und es gibt bereits mehrere gute, daher werde ich nicht versuchen, etwas hinzuzufügen), aber Sie haben Folgendes erwähnt:

Kann mir jemand mit etwas mehr Java/JSP-Erfahrung bitte einige Hinweise geben, wie ich diesen Code so ändern kann es ist eher “Best Practice”, was auch immer das sein mag?

Meiner Meinung nach ist es in Bezug auf JSP am besten, es ausschließlich als Templating-Engine, und nicht mehr (dh keine Geschäftslogik darin). Die Verwendung von JSTL hilft Ihnen, wie viele betonten, definitiv, dorthin zu gelangen, aber selbst mit JSTL ist es einfach, zu viel in einer JSP zu tun.

Ich persönlich halte mich gerne an die Regeln in Erzwingen einer strikten Trennung von Modellansichten in Templating-Engines von Terence Parr bei der Entwicklung in JSP. Das Papier erwähnt den Zweck von Templating-Engines (Trennung von Modell und Ansicht) und die Eigenschaften eines guten Templating-Engines. Es wirft einen guten Blick auf JSP und weist darauf hin, dass es keine gute Templating-Engine ist. Es überrascht nicht, dass JSP im Grunde zu leistungsfähig ist und Entwicklern zu viel erlaubt. Ich empfehle dringend, dieses Dokument zu lesen, und es wird Ihnen helfen, sich auf die “guten” Teile von JSP zu beschränken.

Wenn Sie nur einen Abschnitt in diesem Papier lesen, lesen Sie Kapitel 7, das die folgenden Regeln enthält:

  1. Die Ansicht kann das Modell weder durch direktes Ändern von Modelldatenobjekten noch durch Aufrufen von Methoden für das Modell, die Nebeneffekte verursachen, modifizieren.
    Das heißt, eine Vorlage kann auf Daten aus dem Modell zugreifen und Methoden aufrufen, aber solche Verweise müssen frei von Nebeneffekten sein. Diese Regel entsteht teilweise, weil Datenreferenzen reihenfolgeunabhängig sein müssen. Siehe Abschnitt 7.1.
  2. Die Ansicht kann keine Berechnungen mit abhängigen Datenwerten durchführen denn die Berechnungen können sich in Zukunft ändern und sollten auf jeden Fall sauber im Modell gekapselt werden. Beispielsweise kann die Ansicht keine Buchverkaufspreise als „$price*.90“ berechnen. Um vom Modell unabhängig zu sein, kann die Ansicht keine Annahmen über die Bedeutung von Daten treffen.
  3. Die Ansicht kann abhängige Datenwerte nicht vergleichen, kann aber die Eigenschaften von Daten wie Vorhandensein/Fehlen oder Länge eines mehrwertigen Datenwerts testen. Tests wie $Blutdruck<120 müssen in das Modell verschoben werden, da Ärzte den maximalen systolischen Druck bei uns gerne weiter reduzieren. Ausdrücke in der Ansicht müssen durch einen Test auf das Vorhandensein eines Werts ersetzt werden, der einen booleschen Wert simuliert, wie z. B. $bloodPressureOk!=null. Die Vorlagenausgabe kann von Modelldaten und Berechnungen abhängig sein, die Bedingung muss nur im Modell berechnet werden . Auch einfache Tests, die negative Werte rot machen, sollten im Modell berechnet werden; Die richtige Abstraktionsebene ist normalerweise eine höhere Ebene wie „Abteilung x verliert Geld“.
  4. Die Ansicht kann keine Datentypannahmen treffen. Einige Typannahmen sind offensichtlich, wenn die Ansicht zum Beispiel annimmt, dass ein Datenwert ein Datum ist, aber subtilere Typannahmen treten auf: Wenn ein Template annimmt, dass $userID eine Ganzzahl ist, kann der Programmierer diesen Wert nicht in einen Nichtwert ändern -numerisch im Modell, ohne die Vorlage zu brechen. Diese Regel verbietet die Indizierung von Arrays wie colorCode[$topic] und $name[$ID] Die Sicht kann ferner keine Methoden mit Argumenten aufrufen, weil es (statisch oder dynamisch) einen angenommenen Argumenttyp gibt, es sei denn, man könnte garantieren, dass die Modellmethode sie lediglich als Objekte behandelt. Außerdem sind Grafikdesigner keine Programmierer; zu erwarten, dass sie Methoden aufrufen und wissen, was zu passieren ist, ist unrealistisch.
  5. Daten aus dem Modell dürfen keine Anzeige- oder Layoutinformationen enthalten.
    Das Modell kann keine Anzeigeinformationen getarnt als Datenwerte an die Ansicht übergeben. Dazu gehört, dass der Name einer Vorlage nicht übergeben wird, um sie auf andere Datenwerte anzuwenden.

Übrigens hat Terence seine eigene Templating-Engine namens erstellt String-Vorlage was angeblich diese Regeln wirklich gut durchsetzt. Ich habe keine persönliche Erfahrung damit, würde es aber gerne bei meinem nächsten Projekt ausprobieren.

Sie können mit der Verwendung von Tag-Bibliotheken beginnen. Sie können die Standard-Tag-Bibliothek verwenden JSTL um die meisten der üblichen Dinge zu tun, für die Sie Skripte benötigen. Es gibt viele andere reichhaltigere Tag-Bibliotheken, die wie im Struts2-Framework oder von Apache verwendet werden.

z.B

  <c:if test="${your condition}">
       Your Content
  </c:if>

würde Ihre if-Anweisungen ersetzen.

1643916432 222 Wie vermeide ich die Verwendung von Skriptlets auf meiner JSP Seite
Chris

Die bevorzugte Alternative zu Skriptlets ist die Ausdruckssprache JSTL; Hierist eine gute Übersicht. Sie müssen die Taglib wie folgt hinzufügen:

<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c' %>

Beispielsweise stellt JSTL eine Reihe impliziter Objekte bereit, die Ihnen alles geben, was Sie brauchen. der du willst ist pageContext.request.

Kann man also ersetzen <%request.getRequestURI%> mit ${pageContext.request.requestURI}.

Sie können Bedingungen mit ausführen <c:if> Stichworte.

Sie müssen ein Webframework verwenden. Oder zumindest ein praktisches Taglib. Oder eine Templating-Engine wie FreeMarker.

Anzeigen-Frameworks:

Wenn Sie die JSP-Codierung mögen, würde ich vorschlagen Streben 2.

<s:if test="%{false}">
    <div>Will Not Be Executed</div>
</s:if>
<s:elseif test="%{true}">
    <div>Will Be Executed</div>
</s:elseif>
<s:else>
    <div>Will Not Be Executed</div>
</s:else>

Dann gibt es komponentenorientiert JSF.

Wenn Sie OOP mögen und alles in Java programmieren, versuchen Sie es Apache Wicket (mein Favorit) bzw Google Web-Toolkit.

.

759230cookie-checkWie vermeide ich die Verwendung von Skriptlets auf meiner JSP-Seite?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy