Wie vermeide ich Java-Code in JSP-Dateien?


1673

Ich bin neu in Java EE und ich weiß, dass so etwas wie die folgenden drei Zeilen

<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>

ist eine alte Art der Codierung und in JSP Version 2 gibt es eine Methode, um Java-Code in JSP-Dateien zu vermeiden. Kann mir bitte jemand die alternativen JSP 2-Zeilen sagen und wie diese Technik heißt?


22
@Koray Tugay, solange die Zählervariable irgendwo vor ihrer Verwendung deklariert ist, ist sie mit Sicherheit gültig ...
Sheldon R.

@SheldonR. Dies ist gültig: <% = counter ++%> oder dies: <%! int counter = 0; int x = counter ++; %> aber nicht: <%! int counter = 0; Zähler ++; %>
Koray Tugay

@KorayTugay, ich meinte, wenn der Variablenzähler in einem früheren Skriptblock deklariert wurde, sollte er in einem späteren Block gültig sein. Aber letztendlich sollten J2EE-Programmierer heutzutage sowieso EL-Variablen anstelle von Scriptlets verwenden ...
Sheldon R.

Antworten:


1971

Die Verwendung von Scriptlets (diese <% %>Dinge) in JSP wird seit der Geburt von Taglibs (wie JSTL ) und EL ( Expression Language , diese ${}Dinge) im Jahr 2001 in der Tat dringend empfohlen .

Die Hauptnachteile von Scriptlets sind:

  1. Wiederverwendbarkeit: Sie können Scriptlets nicht wiederverwenden.
  2. Austauschbarkeit: Sie können Scriptlets nicht abstrakt machen.
  3. OO-Fähigkeit: Sie können Vererbung / Komposition nicht verwenden.
  4. Debugbarkeit: Wenn das Scriptlet eine Ausnahme zur Hälfte auslöst, erhalten Sie nur eine leere Seite.
  5. Testbarkeit: Scriptlets können nicht auf Einheiten getestet werden.
  6. Wartbarkeit: Pro Saldo wird mehr Zeit benötigt, um die vermischte / überfüllte / duplizierte Codelogik aufrechtzuerhalten.

Sun Oracle selbst empfiehlt in den JSP-Codierungskonventionen auch , die Verwendung von Scriptlets zu vermeiden, wenn (Tag-) Klassen dieselbe Funktionalität ermöglichen. Hier sind einige relevante Zitate:

Ab der JSP 1.2-Spezifikation wird dringend empfohlen, die JSP Standard Tag Library (JSTL) in Ihrer Webanwendung zu verwenden, um den Bedarf an JSP-Scriptlets auf Ihren Seiten zu verringern . Seiten, die JSTL verwenden, sind im Allgemeinen einfacher zu lesen und zu pflegen.

...

Wenn möglich, vermeiden JSP Scriptlets , wenn Tag - Bibliotheken entsprechende Funktionalität bereitzustellen. Dies erleichtert das Lesen und Verwalten von Seiten, hilft, Geschäftslogik von Präsentationslogik zu trennen, und erleichtert die Entwicklung Ihrer Seiten zu Seiten im JSP 2.0-Stil (JSP 2.0-Spezifikation unterstützt die Verwendung von Scriptlets, betont sie jedoch nicht).

...

Im Sinne der Übernahme des MVC-Entwurfsmusters (Model View Controller), um die Kopplung zwischen der Präsentationsebene und der Geschäftslogik zu verringern, sollten JSP-Scriptlets nicht zum Schreiben von Geschäftslogik verwendet werden. Stattdessen werden JSP-Scriptlets bei Bedarf verwendet, um Daten (auch als "Wertobjekte" bezeichnet), die von der Verarbeitung der Clientanforderungen zurückgegeben wurden, in ein geeignetes Client-fähiges Format umzuwandeln. Selbst dann wäre dies besser mit einem Front-Controller-Servlet oder einem benutzerdefinierten Tag möglich.


Wie Scriptlets vollständig ersetzt werden, hängt vom alleinigen Zweck des Codes / der Logik ab. Mehr als oft soll dieser Code in eine vollwertige Java-Klasse eingefügt werden:

  • Wenn Sie bei jeder Anforderung denselben Java-Code aufrufen möchten, unabhängig von der angeforderten Seite, weniger oder mehr, z. B. prüfen, ob ein Benutzer angemeldet ist, implementieren Sie einen Filter und schreiben Sie den Code entsprechend in die Methode. Z.B:doFilter()

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
            ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page.
        } else {
            chain.doFilter(request, response); // Logged in, just continue request.
        }
    }

    Wenn Sie einem geeigneten Titel zugeordnet sind <url-pattern>, der die interessierenden JSP-Seiten abdeckt, müssen Sie nicht denselben Code für die gesamten JSP-Seiten kopieren.


  • Wenn Sie einige Java - Code aufrufen möchten vorverarbeiten eine Anfrage, zB Vorbelastung einige Liste aus einer Datenbank in irgendeiner Tabelle anzuzeigen, falls erforderlich auf einigen Abfrageparameter basiert, implementieren dann ein Servlet und Schreibcode entsprechend in doGet()Verfahren. Z.B:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            List<Product> products = productService.list(); // Obtain all products.
            request.setAttribute("products", products); // Store products in request scope.
            request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table.
        } catch (SQLException e) {
            throw new ServletException("Retrieving products failed!", e);
        }
    }

    Auf diese Weise ist der Umgang mit Ausnahmen einfacher. Auf die Datenbank wird nicht während des JSP-Renderings zugegriffen, sondern lange bevor die JSP angezeigt wird. Sie haben weiterhin die Möglichkeit, die Antwort zu ändern, wenn der DB-Zugriff eine Ausnahme auslöst. Im obigen Beispiel wird die Seite mit dem Standardfehler 500 angezeigt, die Sie ohnehin durch ein <error-page>In anpassen können web.xml.


  • Wenn Sie Java-Code aufrufen möchten, um eine Anforderung nachzubearbeiten , z. B. die Verarbeitung eines Formulars, dann implementieren Sie ein Servlet und schreiben Sie den entsprechenden Code in die doPost()Methode. Z.B:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);
    
        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            response.sendRedirect("home"); // Redirect to home page.
        } else {
            request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope.
            request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error.
        }
    }

    Auf diese Weise ist der Umgang mit verschiedenen Zielseitenzielen einfacher: erneutes Anzeigen des Formulars mit Validierungsfehlern im Fehlerfall (in diesem Beispiel können Sie es ${message}in EL erneut anzeigen ) oder bei Erfolg einfach zur gewünschten Zielseite wechseln.


  • Wenn Sie Java-Code aufrufen möchten, um den Ausführungsplan und / oder das Ziel der Anforderung und der Antwort zu steuern , implementieren Sie ein Servlet gemäß dem Front Controller-Muster der MVC . Z.B:

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Action action = ActionFactory.getAction(request);
            String view = action.execute(request, response);
    
            if (view.equals(request.getPathInfo().substring(1)) {
                request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
            } else {
                response.sendRedirect(view);
            }
        } catch (Exception e) {
            throw new ServletException("Executing action failed.", e);
        }
    }

    Oder verwenden Sie einfach ein MVC-Framework wie JSF , Spring MVC , Wicket usw., sodass Sie nur eine JSP / Facelets-Seite und eine JavaBean-Klasse erhalten, ohne dass ein benutzerdefiniertes Servlet erforderlich ist.


  • Wenn Sie Java-Code aufrufen möchten, um den Fluss innerhalb einer JSP-Seite zu steuern , müssen Sie eine (vorhandene) Taglib zur Flusssteuerung wie den JSTL-Kern abrufen . ZB Anzeige List<Product>in einer Tabelle:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    ...
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td>${product.name}</td>
                <td>${product.description}</td>
                <td>${product.price}</td>
            </tr>
        </c:forEach>
    </table>

    Mit XML-Tags, die gut zu all dem HTML passen, ist der Code besser lesbar (und damit besser zu warten) als eine Reihe von Scriptlets mit verschiedenen öffnenden und schließenden Klammern ( "Wo zum Teufel gehört diese schließende Klammer hin?" ). Eine einfache Hilfe besteht darin, Ihre Webanwendung so zu konfigurieren, dass eine Ausnahme ausgelöst wird, wenn noch Scriptlets verwendet werden, indem Sie Folgendes hinzufügen web.xml:

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

    In Facelets , dem Nachfolger von JSP, das Teil des von Java EE bereitgestellten MVC-Frameworks JSF ist , können Scriptlets bereits nicht verwendet werden . Auf diese Weise werden Sie automatisch gezwungen, die Dinge "richtig" zu machen.


  • Wenn Sie Java-Code aufrufen möchten, um auf "Backend" -Daten innerhalb einer JSP-Seite zuzugreifen und diese anzuzeigen , müssen Sie EL (Expression Language) verwenden ${}. ZB erneutes Anzeigen der übermittelten Eingabewerte:

    <input type="text" name="foo" value="${param.foo}" />

    Das ${param.foo}zeigt das Ergebnis von request.getParameter("foo").


  • Wenn Sie Java-Code für Dienstprogramme direkt auf der JSP-Seite aufrufen möchten (normalerweise public staticMethoden), müssen Sie diese als EL-Funktionen definieren. In JSTL gibt es eine Taglib für Standardfunktionen , aber Sie können Funktionen auch einfach selbst erstellen . Hier ist ein Beispiel, wie JSTL fn:escapeXmlnützlich ist, um XSS- Angriffe zu verhindern .

    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
    ...
    <input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />

    Beachten Sie, dass die XSS-Empfindlichkeit in keiner Weise speziell mit Java / JSP / JSTL / EL / was auch immer zusammenhängt. Dieses Problem muss in jeder von Ihnen entwickelten Webanwendung berücksichtigt werden . Das Problem von Scriptlets ist, dass sie keine Möglichkeit zur integrierten Verhinderung bieten, zumindest nicht unter Verwendung der Standard-Java-API. Der Nachfolger von JSP, Facelets, hat bereits implizites HTML-Escape-Verfahren, sodass Sie sich keine Gedanken über XSS-Lücken in Facelets machen müssen.

Siehe auch:


117
+1 Tolle Antwort. Aber nicht dogmatisch werden, manchmal ist die Verwendung von Scriptlets in Ordnung, aber das sollte die Ausnahme sein, die die Regel bestätigt.
Svachon

26
@svachon: Scriptlets sind nützlich für schnelles Prototyping / Testen. Soweit ich weiß, gibt es nur eine "legitime" Produktionsverwendung eines Scriptlets, nämlich <% response.getWriter().flush(); %>zwischen </head>und <body>, um die Parsing-Leistung von Webseiten im Webbrowser zu verbessern. Diese Verwendung ist jedoch wiederum völlig vernachlässigbar, wenn die Größe des Ausgabepuffers auf der Serverseite niedrig ist (1 ~ 2 KB). Siehe auch diesen Artikel .
BalusC

5
@BalusC Ein paar Mal habe ich mich mit Java-Klassen beschäftigt, die nicht dem Getter / Setter-Muster folgten. IMHO ist das ein Fall, in dem ein Scripltet die Arbeit erledigt.
Svachon

41
@svachon: Ich würde diese Klassen mit eigenen Javabean-Klassen umschließen und sie stattdessen verwenden.
BalusC

31
Es war eine ziemlich gute Antwort, aber die Teile doGet und doPost sind irreführend. Diese Methoden dienen zur Verarbeitung spezifischer Anforderungsmethoden (HEAD, GET und POST) und nicht zur "Vorverarbeitung" oder "Nachbearbeitung" von Anforderungen!
MetroidFan2002

225

Zum Schutz: Deaktivieren Sie Scriptlets endgültig

Während eine andere Frage diskutiert wird, können und sollten Sie Scriptlets in Ihrem web.xmlWebanwendungsdeskriptor deaktivieren .

Ich würde das immer tun, um zu verhindern, dass Entwickler Scriptlets hinzufügen, insbesondere in größeren Unternehmen, in denen Sie früher oder später den Überblick verlieren. Die web.xmlEinstellungen sehen folgendermaßen aus:

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

4
Deaktiviert dies auch Scriptlet-Kommentare?: <%-- comment that i don't want in the final HTML --%>. Ich finde es nützlich, diese anstelle von HTML-Kommentaren zu verwenden.
David Lavender

16
@ MrSpoon hat eine Antwort für Sie gefunden. Gemäß dieser Antwort + Kommentar , dieser schaltet sich aus Scriptlets <% %>, scriptlet Ausdrücke <%! %>und scriptlet Erklärungen <%= %>. Das bedeutet, dass Anweisungen <%@ %>und Kommentare <%-- --%>aktiviert und verwendbar bleiben, sodass Sie weiterhin Kommentare und Einschlüsse vornehmen können.
Martin Carney

3
Das Deaktivieren von Scriptlet-Anweisungen wäre schrecklich - das Trimmen von Leerzeichen ist von unschätzbarem Wert für die Interaktion mit Legacy-Systemen, die mit zusätzlichen Leerzeichen ausflippen.
CorsiKa

108

JSTL bietet Tags für Bedingungen, Schleifen, Mengen, Abrufe usw. an. Zum Beispiel:

<c:if test="${someAttribute == 'something'}">
   ...
</c:if>

JSTL arbeitet mit Anfrage Eigenschaften - sie sind am häufigsten festgelegt in der Anfrage von einem Servlet, die nach vorne an die JSP.


2
Warum arbeitet JSTL Ihrer Meinung nach mit Anforderungsattributen? Sie können mit Attributen in jedem Bereich arbeiten, nicht wahr?
Koray Tugay

60

Ich bin mir nicht sicher, ob ich das richtig verstehe.

Sie sollten etwas über MVC lesen. Spring MVC & Struts 2 sind die beiden gängigsten Lösungen.


29
MVC kann mit Servlets / JSP unter Verwendung vieler der oben genannten Techniken ohne Feder oder Federbeine implementiert werden.
Stepanian

18
Wie beantwortet es die Frage?
XYZ

54

Sie können JSTL-Tags zusammen mit EL-Ausdrücken verwenden, um eine Vermischung von Java- und HTML-Code zu vermeiden:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
    <head>
    </head>
    <body>

        <c:out value="${x + 1}" />
        <c:out value="${param.name}" />
        // and so on

    </body>
</html>

34

Es gibt auch komponentenbasierte Frameworks wie Wicket , die einen Großteil des HTML-Codes für Sie generieren. Die Tags, die im HTML-Code landen, sind äußerst einfach und es gibt praktisch keine Logik, die eingemischt wird. Das Ergebnis sind fast leere HTML-Seiten mit typischen HTML-Elementen. Der Nachteil ist, dass die Wicket- API viele Komponenten zu lernen hat und einige Dinge unter diesen Bedingungen schwierig zu erreichen sein können.


33

Im MVC-Architekturmuster repräsentieren JSPs die Ansichtsebene. Das Einbetten von Java-Code in JSPs wird als schlechte Praxis angesehen. Sie können JSTL , freeMarker , Geschwindigkeit mit JSP als "Template Engine" verwenden. Der Datenprovider für diese Tags hängt von den Frameworks ab , mit denen Sie sich befassen. Struts 2und webworkals Implementierung für MVC verwendet Pattern OGNL "sehr interessante Technik, um Beans-Eigenschaften für JSP verfügbar zu machen".


27

Die Erfahrung hat gezeigt, dass JSPs einige Mängel aufweisen, von denen eine schwer zu vermeiden ist, Markups mit tatsächlichem Code zu mischen.

Wenn Sie können, sollten Sie eine spezielle Technologie für Ihre Aufgaben in Betracht ziehen. In Java EE 6 gibt es JSF 2.0, das viele nette Funktionen bietet, einschließlich des Zusammenklebens von Java-Beans mit JSF-Seiten durch den #{bean.method(argument)}Ansatz.


3
Alte Antwort, aber ich kann nicht widerstehen zu sagen, dass JSF eine der schrecklichsten Erfindungen im Java-Raum ist. Versuchen Sie, einen einzelnen Link (HTTP GET like) zu erstellen, und Sie werden verstehen, warum.
Alex

@ Alex aber noch besser. Fühlen Sie sich frei, etwas noch besseres zu empfehlen.
Thorbjørn Ravn Andersen

26

Wenn Sie einfach die Nachteile der Java-Codierung in JSP vermeiden möchten, können Sie dies auch mit Scriplets tun. Befolgen Sie einfach eine gewisse Disziplin, um ein minimales Java in JSP und fast keine Berechnung und Logik auf der JSP-Seite zu haben.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%//instantiate a JSP controller
MyController clr = new MyController(request, response);

//process action if any
clr.process(request);

//process page forwaring if necessary

//do all variable assignment here
String showMe = clr.getShowMe();%>

<html>
    <head>
    </head>
    <body>
        <form name="frm1">
            <p><%= showMe %>
            <p><% for(String str : clr.listOfStrings()) { %>
            <p><%= str %><% } %>

            // and so on   
        </form>
    </body>
</html>

26

Erfahren Sie, wie Sie Ihre eigenen Tags mit JSTL anpassen und schreiben

Beachten Sie, dass EL EviL ist (Laufzeitausnahmen, Refactoring).
Wicket kann auch böse sein (Leistung, mühsam für kleine Apps oder einfache Ansichtsebene).

Beispiel aus Java2s ,

Dies muss zur web.xml der Webanwendung hinzugefügt werden

<taglib>
    <taglib-uri>/java2s</taglib-uri>
    <taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>

Datei erstellen: java2s.tld im / WEB-INF /

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<!-- a tab library descriptor -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>Java2s Simple Tags</short-name>

    <!-- this tag manipulates its body content by converting it to upper case
    -->
    <tag>
        <name>bodyContentTag</name>
        <tag-class>com.java2s.BodyContentTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
          <name>howMany</name>
        </attribute>
    </tag>
</taglib>

Kompilieren Sie den folgenden Code in WEB-INF \ classes \ com \ java2s

package com.java2s;

import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyContentTag extends BodyTagSupport{
    private int iterations, howMany;

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

    public void setBodyContent(BodyContent bc){
        super.setBodyContent(bc);
        System.out.println("BodyContent = '" + bc.getString() + "'");
    }

    public int doAfterBody(){
        try{    
            BodyContent bodyContent = super.getBodyContent();
            String bodyString  = bodyContent.getString();
            JspWriter out = bodyContent.getEnclosingWriter();

            if ( iterations % 2 == 0 ) 
                out.print(bodyString.toLowerCase());
            else
                out.print(bodyString.toUpperCase());

            iterations++;
            bodyContent.clear(); // empty buffer for next evaluation
        }
        catch (IOException e) {
            System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
            e.printStackTrace();
        } // end of catch

        int retValue = SKIP_BODY;

        if ( iterations < howMany ) 
            retValue = EVAL_BODY_AGAIN;

        return retValue;
    }
}

Starten Sie den Server und laden Sie die Datei bodyContent.jsp in den Browser

<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
    <head>
        <title>A custom tag: body content</title>
    </head>
    <body>
        This page uses a custom tag manipulates its body content.Here is its output:
        <ol>
            <java2s:bodyContentTag howMany="3">
            <li>java2s.com</li>
            </java2s:bodyContentTag>
        </ol>
    </body>
</html>

Obwohl die Wiederverwendbarkeit von Komponenten in Ordnung ist, zielt sie auf einige Felder ab
Tomasb

25

Wicket ist auch eine Alternative, die Java vollständig von HTML trennt, sodass Designer und Programmierer zusammenarbeiten und an verschiedenen Codesätzen arbeiten können, ohne sich gegenseitig zu verstehen.

Schau dir Wicket an.


23

Sie haben eine gute Frage gestellt, und obwohl Sie gute Antworten erhalten haben, würde ich vorschlagen, dass Sie JSP loswerden. Es ist veraltete Technologie, die irgendwann sterben wird. Verwenden Sie einen modernen Ansatz wie Template-Engines. Sie haben eine sehr klare Trennung zwischen Geschäfts- und Präsentationsebenen und sicherlich keinen Java-Code in Vorlagen, sodass Sie Vorlagen direkt aus der Software zur Bearbeitung von Webpräsentationen generieren können, wobei Sie in den meisten Fällen WYSIWYG nutzen.

Halten Sie sich auf jeden Fall von Filtern und Vor- und Nachbearbeitung fern, da Sie sonst möglicherweise Probleme mit Support / Debugging haben, da Sie immer nicht wissen, woher die Variable den Wert bezieht.


9
JSP ist selbst eine Template-Engine
WarFox

1
-1 - Es gibt viele völlig gültige Gründe für die Verwendung von Filtern, Vorprozessoren und Nachprozessoren. Ja, Sie können Werte erhalten, die mysteriös erscheinen, aber nicht, wenn Sie Ihre Architektur verstehen.
RustyTheBoyRobot

21

Um Java-Code in JSP-Dateien zu vermeiden, stellt Java jetzt Tag-Bibliotheken wie JSTL zur Verfügung. Java hat JSF entwickelt, in das Sie alle Programmierstrukturen in Form von Tags schreiben können


21

Egal wie viel Sie vermeiden möchten, wenn Sie mit anderen Entwicklern zusammenarbeiten, bevorzugen einige von ihnen immer noch das Scriptlet und fügen dann den bösen Code in das Projekt ein. Daher ist das Einrichten des Projekts beim ersten Zeichen sehr wichtig, wenn Sie den Scriptlet-Code wirklich reduzieren möchten. Es gibt verschiedene Techniken, um dies zu überwinden (einschließlich mehrerer Frameworks, die andere erwähnt haben). Wenn Sie jedoch die reine JSP-Methode bevorzugen, verwenden Sie die JSTL-Tag-Datei. Das Schöne daran ist, dass Sie auch Masterseiten für Ihr Projekt einrichten können, damit die anderen Seiten die Masterseiten erben können

Erstellen Sie unter Ihren WEB-INF / -Tags eine Masterseite mit dem Namen base.tag mit dem folgenden Inhalt

<%@tag description="Overall Page template" pageEncoding="UTF-8"%>

<%@attribute name="title" fragment="true" %>

<html>
  <head>
    <title>  
       <jsp:invoke fragment="title"></jsp:invoke>
    </title>

  </head>
  <body>
    <div id="page-header">
       ....
    </div>
    <div id="page-body">
      <jsp:doBody/>
    </div>
    <div id="page-footer">
      .....
    </div>
  </body>
</html>

Auf dieser Mater-Seite habe ich ein Fragment namens "title" erstellt, damit ich auf der untergeordneten Seite weitere Codes an dieser Stelle der Masterseite einfügen kann. Außerdem wird das Tag <jsp:doBody/>durch den Inhalt der untergeordneten Seite ersetzt

Erstellen Sie eine untergeordnete Seite (child.jsp) in Ihrem WebContent-Ordner:

<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:base>
    <jsp:attribute name="title"> 
        <bean:message key="hello.world" />
    </jsp:attribute>

    <jsp:body>
    [Put your content of the child here]
    </jsp:body>   
</t:base>

<t:base>wird verwendet, um die Masterseite anzugeben, die Sie verwenden möchten (derzeit base.tag). Der gesamte Inhalt des Tags <jsp:body>hier ersetzt den <jsp:doBody/>auf Ihrer Masterseite. Ihre untergeordnete Seite kann auch eine beliebige Tag-Bibliothek enthalten und Sie können sie normalerweise wie die andere erwähnte verwenden. Wenn Sie hier jedoch einen Scriptlet-Code verwenden ( <%= request.getParameter("name") %>...) und versuchen, diese Seite auszuführen, erhalten Sie eine JasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here. Daher können andere Personen den bösen Code auf keinen Fall in die JSP-Datei aufnehmen

Aufrufen dieser Seite von Ihrem Controller aus:

Sie können die Datei child.jsp einfach von Ihrem Controller aus aufrufen. Dies funktioniert auch gut mit dem Strebenrahmen


"Egal wie viel Sie vermeiden möchten, wenn Sie mit anderen Entwicklern zusammenarbeiten, bevorzugen einige von ihnen immer noch das Scriptlet und fügen dann den bösen Code in das Projekt ein." Siehe Antwort "Zum Schutz: Deaktivieren von Scriptlets für immer".
Lluis Martinez


18

Verwenden Sie einfach das JSTL-Tag und den EL-Ausdruck.


17

Wenn jemand wirklich gegen das Programmieren in mehr als einer Sprache ist , schlage ich GWT vor. Theoretisch können Sie alle JS- und HTML-Elemente vermeiden, da Google Toolkit den gesamten Client und den gemeinsam genutzten Code in JS umwandelt und Sie keine Probleme damit haben Sie haben einen Webservice ohne Codierung in einer anderen Sprache. Sogar Sie können Standard-CSS von irgendwoher verwenden, wie es durch Erweiterungen (smartGWT oder Vaadin) gegeben ist. Sie müssen nicht Dutzende von Anmerkungen lernen.

Wenn Sie möchten, können Sie sich natürlich in die Tiefen des Codes hacken und JS einfügen und Ihre HTML-Seite anreichern, aber Sie können es wirklich vermeiden, wenn Sie möchten, und das Ergebnis wird gut sein, wie es in anderen Frameworks geschrieben wurde. Ich sage, es ist einen Versuch wert, und die grundlegende GWT ist gut dokumentiert.

Und natürlich haben viele Programmierkollegen hiermit mehrere andere Lösungen beschrieben oder empfohlen. GWT ist für Leute gedacht, die sich wirklich nicht mit dem Webpart befassen oder es minimieren möchten.


1
Beantwortet die Frage des OP nicht wirklich.
Evan Donovan

1
@EvanDonovan gut, praktisch gibt es eine Antwort. Sie müssen sich nicht mit Java-Codes herumschlagen, die sich mit anderen Sprachen vermischen. Ich gebe zu, dass es Java zum Codieren verwendet, aber es wird ohne Java-Aufrufe in JS übersetzt. Die Frage ist jedoch, wie das Chaos der klassischen JSP vermieden werden kann. Und die GWT-Technologie löst das. Ich habe diese Antwort addiert, da niemand sie erwähnt hat, aber relevant, da sie eine Alternative zu JSP darstellt. Ich wollte nicht den gesamten Umfang der Frage beantworten, sondern wertvolle Informationen für Leute hinzufügen, die nach Alternativen suchen.
CsBalazsHungary

16

Eine nette Idee aus der Python-Welt sind Vorlagenattributsprachen . TAL wurde von Zope (daher auch als "Zope Page Templates", ZPT bezeichnet) eingeführt und ist ein Standard mit Implementierungen in PHP, XSLT und Java (ich habe die Inkarnationen Python / Zope und PHP verwendet). In dieser Klasse von Vorlagensprachen könnte ein Beispiel wie folgt aussehen:

<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name">Example product</td>
        <td tal:content="product/description">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

Der Code sieht aus wie normales HTML (oder XHTML) plus einige spezielle Attribute in einem XML-Namespace. Es kann mit einem Browser angezeigt und von einem Designer sicher optimiert werden. Es gibt Unterstützung für Makros und auch für i18n:

<h1 i18n:translate="">Our special offers</h1>
<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name"
            i18n:translate="">Example product</td>
        <td tal:content="product/description"
            i18n:translate="">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

Wenn Übersetzungen des Inhalts verfügbar sind, werden sie verwendet.

Ich weiß jedoch nicht viel über die Java-Implementierung .


1
JSP wurde seit Dezember 2009 von Facelets abgelöst, die dieses Zeug unterstützen. Facelets basiert ebenfalls auf XML. Siehe unter anderem das Kapitel Facelets im Java EE 6-Tutorial und ui:xxxTags in Facelts VDL .
BalusC

Ich kenne Facelets nicht sehr gut, aber beim IIRC geht es darum, Klassen zu schreiben, die benutzerdefinierte XML-Elemente implementieren. Die TAL / ZPT-Methode besteht darin, Vorlagen zu haben, die echtes (X) HTML mit speziellen Attributen enthalten, die die ursprünglichen Elemente füllen oder ersetzen. Auf diese Weise können Sie die Arbeitsvorlage anzeigen und einen Prototyp mit schönem Dummy-Inhalt anzeigen. Ich bin nicht sicher, ob Facelets es erlauben, die ursprünglichen HTML-Elemente (ohne zusätzlichen Namespace) mithilfe benutzerdefinierter Attribute zu optimieren.
Tobias

Ich habe mir gerade dieses Facelets-Zeug noch einmal angesehen. Es enthält alle Arten von Validierungsmöglichkeiten usw. und folgt daher einer völlig anderen Philosophie als TAL. Der TAL-Weg lautet: "Halten Sie die Logik so sauber wie möglich aus der Vorlage heraus. Lassen Sie alle komplizierten Dinge von der Steuerung erledigen, die sie speist." Sie werden einem Designer niemals eine Facelets-Vorlage geben, damit er sie optimiert. es ist einfach nicht möglich. In Bezug auf den generierten Inhalt ist es so, als würde man tal:replace="structure (expression)"ständig Attribute verwenden.
Tobias


14

Sicher, <%! counter++; %>durch eine Ereignisproduzenten-Konsumenten-Architektur ersetzen , bei der die Geschäftsschicht über die Notwendigkeit des Inkrementierens des Zählers informiert wird, entsprechend reagiert und die Präsentatoren benachrichtigt, damit sie die Ansichten aktualisieren. Es handelt sich um eine Reihe von Datenbanktransaktionen, da wir in Zukunft den neuen und alten Wert des Zählers kennen müssen, wer ihn erhöht hat und zu welchem ​​Zweck. Offensichtlich handelt es sich um eine Serialisierung, da die Schichten vollständig entkoppelt sind. Sie können Ihren Zähler über RMI, IIOP, SOAP erhöhen. Es wird jedoch nur HTML benötigt, das Sie nicht implementieren, da es sich um einen so banalen Fall handelt. Ihr neues Ziel ist es, auf Ihrem neuen glänzenden E7-Server mit 64 GB RAM 250 Schritte pro Sekunde zu erreichen.

Ich habe mehr als 20 Jahre Erfahrung in der Programmierung, die meisten Projekte scheitern vor dem Sextett: Wiederverwendbarkeit Austauschbarkeit OO-Fähigkeit Debuggbarkeit Testbarkeit Wartbarkeit ist sogar erforderlich. Andere Projekte, die von Leuten durchgeführt wurden, die sich nur um Funktionalität kümmerten, waren äußerst erfolgreich. Aufgrund der steifen Objektstruktur, die zu früh im Projekt implementiert wurde, kann der Code nicht an die drastischen Änderungen der Spezifikationen angepasst werden (auch bekannt als agil).

Daher betrachte ich die Aktivität des Definierens von "Schichten" oder redundanten Datenstrukturen entweder zu Beginn des Projekts oder wenn dies nicht speziell erforderlich ist, als Aufschub.  


11

Technisch gesehen werden JSP zur Laufzeit alle in Servlets konvertiert . JSP wurde ursprünglich zum Zweck der Entkopplung der Geschäftslogik und der Entwurfslogik nach dem MVC-Muster erstellt. JSP sind also technisch alle Java-Codes zur Laufzeit. Um die Frage zu beantworten, werden Tag-Bibliotheken normalerweise zum Anwenden von Logik (Entfernen von Java-Codes) auf JSP-Seiten verwendet.


8

Wenn wir in einer Java-Webanwendung die folgenden Dinge verwenden, kann Java-Code aus dem Vordergrund der JSP entfernt werden.

  1. Verwenden Sie die MVC-Architektur für Webanwendungen

  2. Verwenden Sie JSP-Tags

    ein. Standard-Tags

    b. Benutzerdefinierte Tags

  3. Ausdruckssprache


8

Wie vermeide ich Java-Code in JSP-Dateien?

Sie können neben Expression Language ( EL ) auch Tab-Bibliotheks-Tags wie JSTL verwenden . Aber EL funktioniert nicht gut mit JSP. Daher ist es wahrscheinlich besser, JSP vollständig zu löschen und Facelets zu verwenden .

Facelets ist die erste Nicht-JSP-Seitendeklarationssprache für JSF (Java Server Faces), die JSF-Entwicklern im Vergleich zu JSP ein einfacheres und leistungsfähigeres Programmiermodell bietet. Es behebt verschiedene Probleme, die in JSP für die Entwicklung von Webanwendungen auftreten.

Geben Sie hier die Bildbeschreibung ein

Quelle


Ich stimme dieser Antwort definitiv zu. JSF mit oder ohne Facelets. Ich dachte, die Entwicklung in JSP hätte vor mehr als 10 Jahren weitgehend aufgehört. Ich habe zuletzt JSPs im Jahr 2000 geschrieben!
Gepäck

4

Die Verwendung von Scriptlets ist ein sehr alter Weg und wird nicht empfohlen. Wenn Sie etwas direkt auf Ihren JSP-Seiten ausgeben möchten, verwenden Sie einfach Expression Language (EL) zusammen mit JSTL .

Es gibt auch andere Optionen wie die Verwendung einer Template-Engine wie Velocity, Freemarker, Thymeleaf usw. Die Verwendung von einfachem JSP mit EL und JSTL erfüllt jedoch meistens meinen Zweck und scheint für Anfänger auch die einfachste zu sein.

Beachten Sie außerdem, dass es keine bewährte Methode ist, Geschäftslogik in der Ansichtsebene auszuführen. Sie sollten Ihre Geschäftslogik in der Serviceebene ausführen und das Ausgabeergebnis über einen Controller an Ihre Ansichten übergeben.


3

Nichts davon wird mehr verwendet, mein Freund. Mein Rat ist, die Ansicht (CSS, HTML, Javascript usw.) vom Server zu entkoppeln.

In meinem Fall mache ich meine Systeme, die die Ansicht mit Angular verarbeiten, und alle benötigten Daten werden mithilfe von Restdiensten vom Server übertragen.

Glauben Sie mir, dies wird Ihre Gestaltung verändern


3

Verwenden Sie ein eckiges Backbone-ähnliches Javascript-Framework für das UI-Design und rufen Sie die Daten mit der Rest-API ab. Dadurch wird die Java-Abhängigkeit vollständig von der Benutzeroberfläche entfernt.


3

JSP 2.0 hat eine Funktion namens "Tag Files" , Sie können Tags ohne externen javaCode schreiben und tld. Sie müssen eine .tagDatei erstellen und einfügen. WEB-INF\tagsSie können sogar eine Verzeichnisstruktur erstellen, um Ihre Tags zu verpacken.

Zum Beispiel:

/WEB-INF/tags/html/label.tag

<%@tag description="Rensders a label with required css class" pageEncoding="UTF-8"%>
<%@attribute name="name" required="true" description="The label"%>

<label class="control-label control-default"  id="${name}Label">${name}</label>

Verwenden Sie es wie

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/html"%>
<h:label  name="customer name" />

Sie können den Tag-Body auch leicht lesen

/WEB-INF/tags/html/bold.tag
<%@tag description="Bold tag" pageEncoding="UTF-8"%>
<b>
  <jsp:doBody/>
</b>

Benutze es

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/bold"%>
<h:bold>Make me bold</h:bold>

Die Beispiele sind sehr einfach, aber Sie können hier viele komplizierte Aufgaben erledigen. Bitte beachten Sie andere Tags verwenden: (zB JSTLdie Tags wie hat Steuern if/forEcah/chosenTextmanipulation wie format/contains/uppercaseoder sogar SQL - Tags select/update, übergeben Sie alle Art Parameter, zum Beispiel) Hashmap, Zugang session, request... in der Tag - Datei zu.

Tag- Dateien sind so einfach zu entwickeln, dass Sie den Server beim Ändern nicht neu starten mussten, wie z. B. JSP-Dateien. Dies erleichtert die Entwicklung.

Selbst wenn Sie ein Framework wie Struts 2 verwenden, das viele gute Tags enthält, können Sie feststellen, dass Ihre eigenen Tags Ihren Code erheblich reduzieren können. Sie können Ihre Tag-Parameter an Struts übergeben und auf diese Weise Ihr Framework-Tag anpassen.

Sie können Tag nicht nur verwenden, um Java zu vermeiden, sondern auch Ihre HTML-Codes zu minimieren. Ich selbst versuche, HTML-Codes zu überprüfen und Tags zu erstellen, sobald auf meinen Seiten Code-Duplikate beginnen.

(Selbst wenn Sie am Ende Java in Ihrem JSP-Code verwenden, was ich nicht hoffe, können Sie diesen Code in ein Tag einkapseln.)


1

Wie in vielen Antworten angegeben, verwenden Sie JSTL oder erstellen Sie Ihre eigenen benutzerdefinierten Tags. Hier finden Sie eine gute Erklärung zum Erstellen benutzerdefinierter Tags


1
  1. Machen Sie Ihre Werte und Parameter in Ihren Servlet-Klassen
  2. Rufen Sie diese Werte und Parameter mit JSTL / Taglib in Ihrer JSP ab

Das Gute an diesem Ansatz ist, dass Ihr Code auch HTML-ähnlicher Code ist!


0

Durch die Verwendung von JSTL-Tags zusammen mit dem EL-Ausdruck können Sie dies vermeiden. Fügen Sie die folgenden Dinge in Ihre JSP-Seite ein:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.