Come evitare il codice Java nei file JSP?


1673

Sono nuovo di Java EE e so che qualcosa come le seguenti tre righe

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

è un vecchio modo di scrivere codice e nella versione 2 di JSP esiste un metodo per evitare il codice Java nei file JSP. Qualcuno può dirmi le linee alternative JSP 2 e come si chiama questa tecnica?


22
@Koray Tugay, fintanto che la variabile counter è dichiarata da qualche parte prima del suo utilizzo, allora è sicuramente valida ...
Sheldon R.

@SheldonR. Questo è valido: <% = counter ++%> o questo: <%! int counter = 0; int x = counter ++; %> ma non: <%! int counter = 0; contatore ++; %>
Koray Tugay,

@KorayTugay, intendevo dire se il contatore delle variabili fosse stato dichiarato in un blocco di script precedente, dovrebbe essere valido in un blocco successivo. Ma alla fine, in questi giorni i programmatori J2EE dovrebbero usare le variabili EL invece degli scriptlet ...
Sheldon R.

Risposte:


1972

L'uso di scriptlet (quelle <% %>cose) in JSP è davvero fortemente scoraggiato dalla nascita di taglibs (come JSTL ) e EL ( Expression Language , quelli${} cose) nel lontano 2001.

I principali svantaggi degli scriptlet sono:

  1. Riusabilità: non è possibile riutilizzare gli scriptlet.
  2. Sostituibilità: non è possibile rendere astratti gli scriptlet.
  3. OO-abilità: non puoi usare l'ereditarietà / composizione.
  4. Debuggabilità: se lo scriptlet genera un'eccezione a metà, tutto ciò che ottieni è una pagina vuota.
  5. Testabilità: gli scriptlet non sono testabili in unità.
  6. Manutenibilità: per saldo è necessario più tempo per mantenere la logica del codice mescolata / ingombra / duplicata.

Sun Oracle stesso raccomanda inoltre nelle convenzioni di codifica JSP di evitare l'uso di scriptlet ogni volta che la stessa funzionalità è possibile per le classi (tag). Ecco alcune citazioni rilevanti:

Dalle specifiche JSP 1.2, si consiglia vivamente di utilizzare la libreria di tag standard JSP (JSTL) nell'applicazione Web per ridurre la necessità di scriptlet JSP nelle pagine. Le pagine che utilizzano JSTL sono, in generale, più facili da leggere e gestire.

...

Ove possibile, evitare gli scriptlet JSP ogni volta che le librerie di tag offrono funzionalità equivalenti. Ciò semplifica la lettura e la gestione delle pagine, aiuta a separare la logica aziendale dalla logica di presentazione e faciliterà l'evoluzione delle pagine in pagine in stile JSP 2.0 (le specifiche JSP 2.0 supportano ma non sottolineano l'uso degli scriptlet).

...

Nello spirito dell'adozione del modello di progettazione modello-view-controller (MVC) per ridurre l'accoppiamento tra il livello di presentazione dalla logica aziendale, gli scriptlet JSP non devono essere utilizzati per scrivere la logica aziendale. Piuttosto, gli scriptlet JSP vengono utilizzati, se necessario, per trasformare i dati (chiamati anche "oggetti valore") restituiti dall'elaborazione delle richieste del client in un formato adeguato pronto per il client. Anche in questo caso, sarebbe meglio farlo con un servlet del front controller o un tag personalizzato.


Come sostituire gli scriptlet dipende interamente dall'unico scopo del codice / della logica. Molto spesso questo codice deve essere inserito in una classe Java pienamente valida:

  • Se si desidera invocare lo stesso codice Java su ogni richiesta, meno o più indipendentemente dalla pagina richiesta, ad esempio controllando se un utente ha effettuato l'accesso, quindi implementare un filtro e scrivere il codice di conseguenza nel doFilter()metodo. Per esempio:

    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.
        }
    }

    Se mappato su un'apposita <url-pattern>copertura delle pagine JSP di interesse, non è necessario copiare nuovamente lo stesso pezzo di codice complessivo delle pagine JSP.


  • Se si desidera invocare un codice Java per preelaborare una richiesta, ad esempio precaricando un elenco da un database da visualizzare in una tabella, se necessario basato su alcuni parametri di query, implementare un servlet e scrivere il codice di conseguenza nel doGet()metodo. Per esempio:

    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);
        }
    }

    In questo modo è più semplice gestire le eccezioni. Al DB non si accede nel mezzo del rendering JSP, ma molto prima che il JSP fosse visualizzato. Hai ancora la possibilità di modificare la risposta ogni volta che l'accesso al DB genera un'eccezione. Nell'esempio sopra, verrà visualizzata la pagina di errore 500 predefinita che è comunque possibile personalizzare con un <error-page>in web.xml.


  • Se si desidera invocare del codice Java per postelaborare una richiesta, ad esempio l'elaborazione di un modulo inoltrato, implementare un servlet e scrivere il codice di conseguenza nel doPost()metodo. Per esempio:

    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.
        }
    }

    In questo modo è più semplice gestire diverse destinazioni della pagina dei risultati: rivisualizzare il modulo con errori di convalida in caso di errore (in questo esempio particolare è possibile visualizzarlo di nuovo utilizzando ${message}in EL ) o semplicemente passare alla pagina di destinazione desiderata in caso di successo.


  • Se si desidera invocare del codice Java per controllare il piano di esecuzione e / o la destinazione della richiesta e della risposta, implementare un servlet secondo il modello di controller anteriore di MVC . Per esempio:

    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);
        }
    }

    O semplicemente adotta un framework MVC come JSF , Spring MVC , Wicket , ecc. In modo da finire con solo una pagina JSP / Facelets e una classe JavaBean senza la necessità di un servlet personalizzato.


  • Se si desidera richiamare del codice Java per controllare il flusso all'interno di una pagina JSP, è necessario acquisire un taglib di controllo del flusso (esistente) come JSTL core . Ad esempio, la visualizzazione List<Product>in una tabella:

    <%@ 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>

    Con tag in stile XML che si adattano perfettamente a tutto l'HTML, il codice è meglio leggibile (e quindi meglio mantenibile) rispetto a un mucchio di scriptlet con varie parentesi graffe di apertura e chiusura ( "Dove diamine appartiene questa parentesi graffa di chiusura?" ). Un semplice aiuto è configurare l'applicazione Web in modo da generare un'eccezione ogni volta che gli scriptlet vengono ancora utilizzati aggiungendo il seguente pezzo a web.xml:

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

    Nel Facelets , il successore di JSP, che fa parte del Java EE fornito framework MVC JSF , è già non è possibile utilizzare scriptlet . In questo modo sei automaticamente costretto a fare le cose "nel modo giusto".


  • Se si desidera invocare del codice Java per accedere e visualizzare i dati "back-end" all'interno di una pagina JSP, è necessario utilizzare EL (Expression Language), queste ${}cose. Ad esempio, rivisualizzando i valori di input inviati:

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

    I ${param.foo}visualizza il risultato di request.getParameter("foo").


  • Se si desidera richiamare un codice Java di utilità direttamente nella pagina JSP (in genere public staticmetodi), è necessario definirli come funzioni EL. C'è un taglib di funzioni standard in JSTL, ma puoi anche creare facilmente funzioni da solo . Ecco un esempio di come JSTL fn:escapeXmlsia utile per prevenire gli attacchi XSS .

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

    Si noti che la sensibilità XSS non è in alcun modo specificamente correlata a Java / JSP / JSTL / EL / qualunque cosa, questo problema deve essere preso in considerazione in ogni applicazione Web sviluppata. Il problema degli scriptlet è che non fornisce alcun modo per prevenire le builtin, almeno non usando l'API Java standard. Il successore di JSP Facelets ha già implicito l'escaping HTML, quindi non devi preoccuparti dei buchi XSS in Facelets.

Guarda anche:


117
+1 Ottima risposta. Ma non andare dogmatico, a volte usare gli scriptlet È ok, ma dovrebbe essere l'eccezione che conferma la regola.
svachon,

26
@svachon: gli scriptlet sono utili per prototipazione / test rapidi. Per quanto ne so, c'è solo un uso "legittimo" della produzione di uno scriptlet, vale a dire <% response.getWriter().flush(); %>tra il </head>e il<body> per migliorare le prestazioni di analisi delle pagine Web nel browser web. Ma questo utilizzo è a sua volta completamente trascurabile quando la dimensione del buffer di output sul lato server è bassa (1 ~ 2 KB). Vedi anche questo articolo .
BalusC,

5
@BalusC Alcune volte sono stato bloccato con le classi java che non seguivano il modello getter / setter. IMHO è un caso in cui uno script fa il lavoro.
svachon,

41
@svachon: Avrei avvolto quelle classi con le proprie classi javabean e le avrei usate invece.
BalusC,

31
È stata una risposta abbastanza buona, ma le parti doGet e doPost sono fuorvianti. Questi metodi sono per la gestione di specifici metodi di richiesta (HEAD, GET e POST) e non per richieste di "preelaborazione" o "postelaborazione"!
MetroidFan2002

225

Come salvaguardia: disabilita gli scriptlet per sempre

Mentre si discute di un'altra domanda , è possibile e sempre disabilitare gli scriptlet nel web.xmldescrittore dell'applicazione Web.

Lo farei sempre per impedire a qualsiasi sviluppatore di aggiungere scriptlet, specialmente nelle aziende più grandi dove prima o poi perderai la visione d'insieme. Ilweb.xml impostazioni sono simili alle seguenti:

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

4
Questo disabilita anche i commenti dello scriptlet ?: <%-- comment that i don't want in the final HTML --%>. Trovo utile usare questi piuttosto che commenti HTML.
David Lavender,

16
@MrSpoon ha rintracciato una risposta per te. In base a questa risposta + commento , vengono disattivati ​​gli scriptlet <% %>, le espressioni degli <%! %>scriptlet e le dichiarazioni degli scriptlet <%= %>. Ciò significa che le direttive <%@ %>e i commenti <%-- --%>rimangono abilitati e utilizzabili, quindi è ancora possibile fare commenti e include.
Martin Carney,

3
La disabilitazione delle direttive degli scriptlet sarebbe terribile: tagliare gli spazi bianchi è prezioso per interagire con i sistemi legacy che vanno fuori di testa con spazi bianchi extra.
corsiKa

108

JSTL offre tag per condizionali, loop, set, get, ecc. Ad esempio:

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

JSTL funziona con gli attributi di richiesta: sono spesso impostati nella richiesta da un Servlet, che inoltra al JSP.


2
Perché dici che JSTL funziona con gli attributi di richiesta? Possono lavorare con attributi in qualsiasi ambito, no?
Koray Tugay,

60

Non sono sicuro che ottenga questo corretto.

Dovresti leggere qualcosa su MVC. Spring MVC & Struts 2 sono le due soluzioni più comuni.


29
MVC può essere implementato con servlet / jsp usando molte delle tecniche di cui sopra senza Spring o Struts.
stepaniano,

18
Come risponde alla domanda?
xyz,

54

È possibile utilizzare i tag JSTL insieme alle espressioni EL per evitare di mescolare codice Java e HTML:

<%@ 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

Esistono anche framework basati su componenti come Wicket che generano molto HTML per te. I tag che finiscono nell'HTML sono estremamente semplici e non c'è praticamente alcuna logica che si mescoli. Il risultato sono pagine HTML quasi vuote con elementi HTML tipici. Il rovescio della medaglia è che ci sono molti componenti nell'API di Wicket da imparare e che alcune cose possono essere difficili da raggiungere con questi vincoli.


33

Nel modello MVC Architectural, i JSP rappresentano il livello Visualizza. Incorporare il codice Java nei JSP è considerato una cattiva pratica. Puoi usare JSTL , freeMarker , velocity con JSP come "motore modello". Il fornitore di dati per quei tag dipende dai framework con cui hai a che fare. Struts 2e webworkcome implementazione per MVC Pattern utilizza OGNL "tecnica molto interessante per esporre Beans Properties a JSP".


27

L'esperienza ha dimostrato che i JSP presentano alcune carenze, una delle quali è difficile evitare di mescolare il markup con il codice reale.

Se puoi, prendi in considerazione l'uso di una tecnologia specializzata per ciò che devi fare. In Java EE 6 c'è JSF 2.0, che offre molte funzioni interessanti tra cui incollare i bean Java insieme alle pagine JSF attraverso l' #{bean.method(argument)}approccio.


3
Vecchia risposta, ma non posso resistere a dire che JSF è una delle invenzioni più orrende nello spazio Java. Prova a creare un singolo link (HTTP GET like) e capirai perché.
Alex,

@Alex ma ancora meglio. Sentiti libero di consigliare qualcosa di ancora meglio.
Thorbjørn Ravn Andersen,

26

se vuoi semplicemente evitare gli svantaggi della codifica Java in JSP, puoi farlo anche con gli script. Basta seguire un po 'di disciplina per avere Java minimo in JSP e quasi nessun calcolo e logica nella pagina JSP.

<%@ 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

Impara a personalizzare e scrivere i tuoi tag usando JSTL

Nota che EL è EviL (eccezioni di runtime, refactoring) Anche il
Wicket può essere malvagio (prestazioni, faticoso per piccole app o livello di visualizzazione semplice)

Esempio da java2s ,

Questo deve essere aggiunto al web.xml dell'applicazione Web

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

creare il file: java2s.tld in / 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>

compila il seguente codice 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;
    }
}

Avviare il server e caricare bodyContent.jsp nel 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>

sebbene la riusabilità dei componenti
vada

25

Wicket è anche un'alternativa che separa completamente java da html, quindi un designer e un programmatore possono lavorare insieme e su diversi set di codice con scarsa comprensione reciproca.

Guarda Wicket.


23

Hai sollevato una buona domanda e sebbene tu abbia avuto buone risposte, suggerirei di sbarazzarti di JSP. È una tecnologia obsoleta che alla fine morirà. Usa un approccio moderno, come i motori di template. Avrai una netta separazione tra livelli aziendali e di presentazione e certamente nessun codice Java nei modelli, quindi puoi generare modelli direttamente dal software di modifica delle presentazioni Web, nella maggior parte dei casi sfruttando WYSIWYG.

E certamente stai alla larga da filtri e pre e post elaborazione, altrimenti potresti avere difficoltà di supporto / debugging poiché non sai sempre dove la variabile ottiene il valore.


9
JSP è esso stesso un motore modello
WarFox,

1
-1 - Esistono molte ragioni completamente valide per utilizzare filtri, pre-processori e post-processori. Sì, puoi finire con valori che sembrano misteriosi, ma non se capisci la tua architettura.
RustyTheBoyRobot,

21

per evitare il codice java nei file JSP java ora fornisce librerie di tag come JSTL anche java ha creato JSF in cui è possibile scrivere tutte le strutture di programmazione sotto forma di tag


21

Indipendentemente da quanto si tenta di evitare, quando si lavora con altri sviluppatori, alcuni preferiranno comunque lo scriptlet e quindi inseriranno il codice malvagio nel progetto. Pertanto, l'impostazione del progetto al primo segno è molto importante se si desidera davvero ridurre il codice dello scriptlet. Esistono diverse tecniche per superare questo (inclusi diversi framework citati da altri). Tuttavia, se si preferisce il modo JSP puro, utilizzare il file tag JSTL. La cosa bella di questo è che puoi anche impostare pagine master per il tuo progetto, in modo che le altre pagine possano ereditare le pagine master

Crea una pagina principale denominata base.tag sotto i tuoi WEB-INF / tag con il seguente contenuto

<%@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>

In questa pagina mater, ho creato un frammento chiamato "titolo", in modo che nella pagina figlio, potessi inserire più codici in questo posto della pagina principale. Inoltre, il tag<jsp:doBody/> verrà sostituito dal contenuto della pagina figlio

Crea una pagina figlio (child.jsp) nella cartella WebContent:

<%@ 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>viene utilizzato per specificare la pagina principale che si desidera utilizzare (che è base.tag in questo momento). Tutto il contenuto all'interno del tag <jsp:body>qui sostituirà la <jsp:doBody/>pagina principale. La tua pagina figlio può anche includere qualsiasi tag lib e puoi usarla normalmente come l'altra menzionata. Tuttavia, se si utilizza un codice scriptlet qui ( <%= request.getParameter("name") %>...) e si tenta di eseguire questa pagina, verrà visualizzato un JasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here. Pertanto, non è possibile che altre persone possano includere il codice malvagio nel file jsp

Chiamare questa pagina dal controller:

Puoi facilmente chiamare il file child.jsp dal tuo controller. Funziona bene anche con il framework degli struts


"Indipendentemente da quanto cerchi di evitare, quando lavori con altri sviluppatori, alcuni di loro preferiranno comunque lo scriptlet e quindi inseriranno il codice malvagio nel progetto." Vedi la risposta "Come salvaguardia: disabilita gli scriptlet per sempre".
Lluis Martinez,



17

Se qualcuno è davvero contrario alla programmazione in più lingue di una , suggerisco GWT, teoricamente puoi evitare tutti gli elementi JS e HTML, poiché Google Toolkit trasforma tutto il client e il codice condiviso in JS, quindi non avrai problemi con loro, quindi hai un servizio web senza codifica in altre lingue. Anche tu puoi usare alcuni CSS predefiniti da qualche parte dato dalle estensioni (smartGWT o Vaadin). Non è necessario imparare dozzine di annotazioni.

Ovviamente, se vuoi, puoi hackerarti nelle profondità del codice e iniettare JS e arricchire la tua pagina HTML, ma in realtà puoi evitarlo se vuoi, e il risultato sarà buono come è stato scritto in qualsiasi altro framework. Dico che vale la pena provare e il GWT di base è ben documentato.

E naturalmente molti altri programmatori descrivono o raccomandano diverse altre soluzioni. GWT è per le persone che non vogliono davvero gestire la web part o minimizzarla.


1
Non risponde davvero alla domanda del PO.
Evan Donovan,

1
@EvanDonovan bene, praticamente dà una risposta. Non è necessario pasticciare con i codici Java che si confondono con altre lingue. Devo ammettere che utilizza Java per la codifica, ma verrà tradotto in JS senza chiamate Java. Ma lo scopo della domanda è come evitare il caos del classico JSP. E la tecnologia GWT lo risolve. Ho aggiunto questa risposta da quando nessuno l'ha menzionata, ma pertinente poiché è un'alternativa a JSP. Non volevo rispondere all'intera portata della domanda, ma aggiungere un'informazione preziosa per le persone che cercano alternative.
CsBalazs Ungheria

16

Un'idea chiara dal mondo Python sono i linguaggi degli attributi Template ; TAL è stato introdotto da Zope (quindi noto anche come "Zope Page Templates", ZPT) ed è uno standard, con implementazioni anche in PHP, XSLT e Java (ho usato le incarnazioni Python / Zope e PHP). In questa classe di linguaggi di template, un esempio sopra potrebbe apparire così:

<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>

Il codice appare come un normale HTML (o XHTML) più alcuni attributi speciali in uno spazio dei nomi XML; può essere visualizzato con un browser ed essere ottimizzato in modo sicuro da un designer. C'è supporto per le macro e anche per 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>

Se sono disponibili traduzioni del contenuto, vengono utilizzate.

Tuttavia, non so molto sull'implementazione di Java .


1
Da dicembre 2009 JSP è stato sostituito da Facelets che supporta questa roba. Facelets è anche basato su XML. Vedi anche, tra gli altri, il capitolo Facelets in Java EE 6 tutorial e ui:xxxtag in Facelts VDL .
BalusC,

Non conosco molto bene Facelets, ma IIRC si basa sulla scrittura di classi che implementano elementi XML personalizzati. Il modo TAL / ZPT è di avere modelli che contengono HTML (X) vero con attributi speciali che riempiono o sostituiscono gli elementi originali; quindi, è possibile visualizzare il modello di lavoro e vedere un prototipo con un contenuto fittizio. Non sono sicuro che Facelets permetta di modificare gli elementi HTML originali (senza uno spazio dei nomi aggiuntivo) usando attributi personalizzati.
Tobias,

Ho appena dato un'altra occhiata a questa roba di Facelets. Contiene tutti i tipi di strumenti di convalida, ecc. E quindi segue una filosofia completamente diversa rispetto a TAL. Il modo TAL è "Mantieni la logica fuori dal modello nel modo più pulito possibile; fai fare tutto il complicato dal controller che lo alimenta". Non darai mai un modello di Facelets a un designer per farlo modificare; non è possibile. Per quanto riguarda il contenuto generato, è come usare sempre gli tal:replace="structure (expression)"attributi.
Tobias,


14

Certo, sostituisci <%! counter++; %>con un'architettura produttore-consumatore di eventi, in cui il livello aziendale viene informato della necessità di incrementare il contatore, reagisce di conseguenza e avvisa i presentatori in modo che aggiornino le viste. Sono coinvolte diverse transazioni di database, poiché in futuro dovremo conoscere il nuovo e vecchio valore del contatore, chi lo ha incrementato e con quale scopo in mente. Ovviamente è coinvolta la serializzazione, poiché i livelli sono completamente disaccoppiati. Sarai in grado di incrementare il tuo contatore su RMI, IIOP, SOAP. Ma è richiesto solo HTML, che non implementate, poiché è un caso così banale. Il tuo nuovo obiettivo è raggiungere 250 incrementi al secondo sul tuo nuovo brillante server RAM E7 da 64 GB.

Ho più di 20 anni di programmazione, la maggior parte dei progetti fallisce prima del sestetto: Riusabilità Sostituibilità Capacità OO Debuggabilità Testabilità La manutenzione è persino necessaria. Altri progetti, gestiti da persone che si preoccupavano solo della funzionalità, hanno avuto un enorme successo. Inoltre, la rigida struttura degli oggetti, implementata troppo presto nel progetto, rende il codice incapace di adattarsi ai drastici cambiamenti delle specifiche (ovvero agili).

Quindi considero come procrastinazione l'attività di definizione di "livelli" o strutture di dati ridondanti all'inizio del progetto o quando non specificamente richiesto.  


11

Tecnicamente, i JSP vengono tutti convertiti in servlet durante il runtime . JSP è stato inizialmente creato allo scopo di disaccoppiare la logica di business e la logica di progettazione, seguendo il modello MVC. Quindi i JSP sono tecnicamente tutti i codici java durante il runtime. Ma per rispondere alla domanda, le librerie di tag vengono generalmente utilizzate per applicare la logica (rimozione di codici Java) alle pagine JSP.


8

Se utilizziamo i seguenti elementi in un'applicazione Web Java, il codice Java può essere eliminato dal primo piano di JSP.

  1. Utilizzare l'architettura MVC per l'applicazione Web

  2. Usa tag JSP

    un. Tag standard

    b. Tag personalizzati

  3. Linguaggio delle espressioni


8

Come evitare il codice Java nei file JSP?

È possibile utilizzare tag della libreria di schede come JSTL oltre a Expression Language ( EL ). Ma EL non funziona bene con JSP. Quindi è probabilmente meglio abbandonare completamente JSP e usare Facelets .

Facelets è il primo linguaggio di dichiarazione delle pagine non JSP progettato per JSF (Java Server Faces) che ha fornito agli sviluppatori JSF un modello di programmazione più semplice e più potente rispetto a JSP. Risolve diversi problemi che si verificano in JSP per lo sviluppo di applicazioni Web.

inserisci qui la descrizione dell'immagine

fonte


Assolutamente secondo questa risposta. JSF con o senza sfaccettature. Pensavo che lo sviluppo in JSP fosse in gran parte cessato più di 10 anni fa. Ho scritto per l'ultima volta JSP nel 2000!
mutuo il

4

L'uso degli scriptlet è un metodo molto vecchio e sconsigliato. Se vuoi produrre direttamente qualcosa nelle tue pagine JSP usa Expression Language (EL) insieme a JSTL .

Ci sono anche altre opzioni come usare un motore di template come Velocity, Freemarker, Thymeleaf ecc. Ma usare JSP semplice con EL e JSTL serve il mio scopo la maggior parte del tempo e sembra anche il più semplice per un principiante.

Inoltre, tenere presente che non è consigliabile eseguire la logica aziendale nel livello di visualizzazione, è necessario eseguire le logiche aziendali nel livello di servizio e passare il risultato di output alle visualizzazioni tramite un controller.


3

Niente di tutto ciò è più usato amico mio, il mio consiglio è di disaccoppiare la vista (css, html, javascript, ecc.) Dal server.

Nel mio caso, i miei sistemi gestiscono la vista con Angular e tutti i dati necessari vengono portati dal server utilizzando i servizi di riposo.

Credetemi, questo cambierà il modo in cui progetti


3

Usa backbone, angolare come framework javascript per la progettazione dell'interfaccia utente e recupera i dati usando api di riposo. Ciò rimuoverà completamente la dipendenza java dall'interfaccia utente.


3

JSP 2.0 ha una funzione chiamata "Tag Files" , puoi scrivere tag senza javacodice esterno e tld. Devi creare un .tagfile e inserirlo, WEB-INF\tagspuoi persino creare una struttura di directory per impacchettare i tuoi tag.

Per esempio:

/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>

Usalo come

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

Inoltre, puoi leggere facilmente il corpo del tag

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

Usalo

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

Gli esempi sono molto semplici ma qui puoi svolgere molte attività complicate. Perche non è possibile utilizzare altri tag (ad esempio: JSTLche ha il controllo tag come if/forEcah/chosenla manipolazione del testo come format/contains/uppercaseo anche i tag SQL select/update), passare tutti i parametri di tipo, ad esempio Hashmap, l'accesso session, request... nel file tag troppo.

I file tag sono così facili da sviluppare in quanto non è stato necessario riavviare il server durante la modifica, come i file JSP. Questo li rende facili per lo sviluppo.

Anche se usi un framework come Struts 2, che ha molti buoni tag, potresti scoprire che avere i tuoi tag può ridurre molto il tuo codice. È possibile passare i parametri del tag ai montanti e in questo modo personalizzare il tag del framework.

Puoi usare il tag non solo per evitare java ma anche minimizzare i tuoi codici HTML. Io stesso provo a rivedere i codici HTML e a creare tag molto non appena vedo i duplicati di codice iniziare nelle mie pagine.

(Anche se finisci per usare java nel tuo codice JSP, cosa che spero di no, puoi incapsulare quel codice in un tag)


1

Come dicono molte risposte, usa JSTL o crea i tuoi tag personalizzati. Ecco una buona spiegazione sulla creazione di tag personalizzati


1
  1. Rendi i tuoi valori e parametri all'interno delle tue classi servlet
  2. Recupera quei valori e parametri nel tuo JSP usando JSTL / Taglib

La cosa buona di questo approccio è che il tuo codice è anche HTML come codice!


0

Usando i tag JSTL insieme all'espressione EL puoi evitarlo. Inserisci le seguenti cose nella tua pagina jsp:

<%@ 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" %>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.