JSP trucchi per rendere il template più semplice?

Al lavoro ho il compito di trasformare un mucchio di HTML file in un semplice JSP progetto. E ‘ davvero tutto statico, non serverside logica di programma. Devo dire che io sono completamente nuovo di Java. JSP file sembrano rendere più facile lavorare con il terreno comprende e variabili, come PHP, ma vorrei sapere un modo semplice per ottenere qualcosa di simile modello di ereditarietà (Django stile), o almeno essere in grado di avere una base.jsp file contenente l’intestazione e il piè di pagina, in modo da poter inserire contenuti in un secondo momento.

Ben Ling sembra offrire qualche speranza nella sua risposta qui:
JSP ereditarietà dei template
Qualcuno può spiegare come farlo?

Dato che non ho molto tempo penso di routing dinamico è un po ‘ troppo, quindi sono felice solo per avere gli Url direttamente sulla mappa .jsp file, ma sono aperto a suggerimenti.

Grazie.

edit: non voglio usare delle librerie esterne, perché consentirebbe di aumentare la curva di apprendimento per me e gli altri che lavorano al progetto, e l’azienda per cui lavoro ha un contratto per fare questo.

Un’altra modifica: non so se JSP tags sarà utile perché il mio contenuto, non la variabili del modello. Ciò di cui ho bisogno è un modo per essere in grado di fare questo:

base.html:

<html><body>
{ content.body }
</body></html>

somepage.html

<wrapper:base.html>
<h1>Welcome</h1>
</wrapper>

con l’uscita:

<html><body>
<h1>Welcome</h1>
</body></html>

Penso che questo mi avrebbe dato abbastanza versatilità per quello di cui ho bisogno. Potrebbe essere raggiunto con includes ma poi avrei bisogno di una parte superiore e una inferiore includere per ogni confezione, che è un po ‘ disordinato.

InformationsquelleAutor Scott | 2009-08-18

 

7 Replies
  1. 673

    Come skaffman suggerito, JSP 2.0 File di Tag sono ginocchia dell’ape.

    Prendiamo il tuo esempio semplice.

    Inserire, nella WEB-INF/tags/wrapper.tag

    <%@tag description="Simple Wrapper Tag" pageEncoding="UTF-8"%>
    <html><body>
      <jsp:doBody/>
    </body></html>

    Ora nel tuo example.jsp pagina:

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
    
    <t:wrapper>
        <h1>Welcome</h1>
    </t:wrapper>

    Che fa esattamente quello che tu pensi.


    Quindi, consente di ampliare il che a qualcosa di un po ‘ più generale.
    WEB-INF/tags/genericpage.tag

    <%@tag description="Overall Page template" pageEncoding="UTF-8"%>
    <%@attribute name="header" fragment="true" %>
    <%@attribute name="footer" fragment="true" %>
    <html>
      <body>
        <div id="pageheader">
          <jsp:invoke fragment="header"/>
        </div>
        <div id="body">
          <jsp:doBody/>
        </div>
        <div id="pagefooter">
          <jsp:invoke fragment="footer"/>
        </div>
      </body>
    </html>

    Di utilizzare questo:

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
    
    <t:genericpage>
        <jsp:attribute name="header">
          <h1>Welcome</h1>
        </jsp:attribute>
        <jsp:attribute name="footer">
          <p id="copyright">Copyright 1927, Future Bits When There Be Bits Inc.</p>
        </jsp:attribute>
        <jsp:body>
            <p>Hi I'm the heart of the message</p>
        </jsp:body>
    </t:genericpage>

    Cosa che si compra? Un sacco davvero, ma è ancora meglio…


    WEB-INF/tags/userpage.tag

    <%@tag description="User Page template" pageEncoding="UTF-8"%>
    <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
    <%@attribute name="userName" required="true"%>
    
    <t:genericpage>
        <jsp:attribute name="header">
          <h1>Welcome ${userName}</h1>
        </jsp:attribute>
        <jsp:attribute name="footer">
          <p id="copyright">Copyright 1927, Future Bits When There Be Bits Inc.</p>
        </jsp:attribute>
        <jsp:body>
            <jsp:doBody/>
        </jsp:body>
    </t:genericpage>

    Di utilizzare questo:
    (supponiamo di avere una variabile utente nella richiesta)

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
    
    <t:userpage userName="${user.fullName}">
      <p>
        First Name: ${user.firstName} <br/>
        Last Name: ${user.lastName} <br/>
        Phone: ${user.phone}<br/>
      </p>
    </t:userpage>

    Ma si trasforma per l’uso che l’utente dettaglio di blocco in altri luoghi. Così, dovremo rifattorizzare.
    WEB-INF/tags/userdetail.tag

    <%@tag description="User Page template" pageEncoding="UTF-8"%>
    <%@tag import="com.example.User" %>
    <%@attribute name="user" required="true" type="com.example.User"%>
    
    First Name: ${user.firstName} <br/>
    Last Name: ${user.lastName} <br/>
    Phone: ${user.phone}<br/>

    Ora l’esempio precedente diventa:

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
    
    <t:userpage userName="${user.fullName}">
      <p>
        <t:userdetail user="${user}"/>
      </p>
    </t:userpage>

    La bellezza di Tag JSP file è che permette fondamentalmente tag generico markup rifattorizzare al contenuto del vostro cuore.

    JSP Tag Files hanno praticamente soppiantato le cose come Tiles ecc…. almeno per me. Io li trovo molto più facile da usare come unica struttura è ciò che si dà, nulla di precostituito. Inoltre è possibile utilizzare tag JSP file per altre cose (come l’utente dettaglio frammento sopra).

    Ecco un esempio che è simile a DisplayTag che ho fatto, ma questo è tutto fatto con i File di Tag (e il Stripes quadro, che il s: tag..). Questo si traduce in una tabella di righe, alternando i colori, la navigazione della pagina, ecc:

    <t:table items="${actionBean.customerList}" var="obj" css_class="display">
      <t:col css_class="checkboxcol">
        <s:checkbox name="customerIds" value="${obj.customerId}"
                    onclick="handleCheckboxRangeSelection(this, event);"/>
      </t:col>
      <t:col name="customerId" title="ID"/>
      <t:col name="firstName" title="First Name"/>
      <t:col name="lastName" title="Last Name"/>
      <t:col>
        <s:link href="/Customer.action" event="preEdit">
          Edit
          <s:param name="customer.customerId" value="${obj.customerId}"/>
          <s:param name="page" value="${actionBean.page}"/>
        </s:link>
      </t:col>
    </t:table>

    Naturalmente le etichette funzionano con JSTL tags (come c:if, etc.). L’unica cosa che non si può fare all’interno del corpo di un file di tag tag aggiungi Java scriptlet codice, ma questo non è tanto un limite, come si potrebbe pensare. Se ho bisogno di scriptlet roba, ho appena messo la logica di un tag e rilasciare i tag. Facile.

    Così, file di tag può essere praticamente qualsiasi cosa che si desidera loro di essere. Al livello più elementare, è semplice taglia e incolla di refactoring. Prendete un pezzo di layout, tagliato fuori, fare qualche semplice parametrizzazione, e sostituirlo con un tag di invocazione.

    A un livello superiore, è possibile eseguire un sofisticato cose come questa tabella tag che ho qui.

    • Grazie per questo. È il miglior tutorial che ho potuto trovare su di tag JSP file, che è stato grande per me venendo da JSF. Vorrei poter fare più di un up al voto.
    • +40milioni. Vi ringrazio per spiegare 50.000 volte meglio di qualsiasi merda tutorial che ho trovato. Provenienti dalle Rotaie mondo e mancanti ERB, questo è esattamente ciò di cui ho bisogno. Si dovrebbe scrivere un blog.
    • Davvero un bel tutorial. Potrebbe condividere con noi il codice per il tag di tabella che hai fatto? Ho creato uno io un po ‘ di tempo fa, ma il tuo approccio è migliore.
    • Molto utile tutorial, grazie mille! Una piccola domanda: quando dici “Se ho bisogno di scriptlet roba, ho appena messo la logica di un tag e rilasciare il tag a.”, è in realtà significa taglib giusto? Perché altrimenti ti sembra di dire che scriptlet codice non può essere utilizzato in un tag, ma una soluzione è aggiungere un altro tag, invece!
    • Se si crea un file di tag tag, il contenuto del tag nel file JSP non può avere scriptlet codice: <t:mytag> no scriptlet qui il codice </t:mytag>. Ma all’interno del file di tag attuazione del tag stesso, che può avere tutti gli scriptlet codice che si desidera, come tutte le JSP.
    • grazie per il tuo grande risposta di prima, ho una domanda: come trattare con tag nidificato nel tag jsp file? Per esempio, nel tuo t:table tag, il t:col deve, in un table, così come ottenere genitore tag quando implementare un bambino di tag?
    • Ho solo roba da cose in luoghi conosciuti all’interno della richiesta, etc. Per esempio il t:table tag, è possibile creare un elenco in _tableColumns di t:col tag popola. Poi, quando t:table esegue jsp:doBody, il t:col aggiungere roba a quella lista, e alla fine, dopo il jsp:doBody, il t:table tag rende le cose nell’elenco, quindi rimuove dalla richiesta.
    • grazie, ho capito il tuo mezzo, è veramente semplice.
    • Nota – sembra che l’ordine dei tag è importante; jsp:attributo deve venire prima di jsp:corpo o si otterrà un messaggio di errore. Inoltre ho dovuto impostare un corrispondente @attributo tag match jsp:invoke per evitare un altro errore. Utilizzando GlassFish 3.2.2
    • tag dei file di fornire prestazioni molto basse, e molto poco di funzionalità rispetto alle piastrelle-3 (ma sono grandi se non hai bisogno di prestazioni, né le funzioni extra, e non c’è niente che ti impedisce di utilizzo di entrambi – ciascuno per soddisfare i loro punti di forza).
    • puoi approfondire la tua performance crediti? Attualmente sto valutando se andare giù il Apache Tiles strada o JSP 2.x i file di tag, e da questa risposta, sembra tag di file rende le cose molto più facile, rispetto al mantenimento del tiles.xml file(s).
    • Così, in ERB, sei in grado di definire un modello di pagina per il rendering di default, che utilizza <%= rendimento %>. Cercando di avvolgere la mia testa intorno come per fare qualcosa di simile in JSP.
    • Solo una nota: Ovviamente devi mettere tutti jsp:attribute prima della jsp:body. Se lo faccio in un altro modo, un errore casuale, come descritto nei link questione appare. stackoverflow.com/questions/30219719/…
    • È possibile per noi attributi in append modo? Per esempio voglio aggiungere il codice javascript attraverso il codice in più luoghi e a rendere alla fine di un layout di base

  2. 21

    Ho fatto abbastanza facile, Django stile ereditarietà dei Template JSP tag library.
    https://github.com/kwon37xi/jsp-template-inheritance

    Penso che si rendono facile per gestire i layout senza curva di apprendimento.

    codice di esempio :

    base.jsp : layout

    <%@page contentType="text/html; charset=UTF-8" %>
    <%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>JSP Template Inheritance</title>
        </head>
    
    <h1>Head</h1>
    <div>
        <layout:block name="header">
            header
        </layout:block>
    </div>
    
    <h1>Contents</h1>
    <div>
        <p>
        <layout:block name="contents">
            <h2>Contents will be placed under this h2</h2>
        </layout:block>
        </p>
    </div>
    
    <div class="footer">
        <hr />
        <a href="https://github.com/kwon37xi/jsp-template-inheritance">jsp template inheritance example</a>
    </div>
    </html>

    vista.jsp : contenuto

    <%@page contentType="text/html; charset=UTF-8" %>
    <%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>
    <layout:extends name="base.jsp">
        <layout:put name="header" type="REPLACE">
            <h2>This is an example about layout management with JSP Template Inheritance</h2>
        </layout:put>
        <layout:put name="contents">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin porta,
            augue ut ornare sagittis, diam libero facilisis augue, quis accumsan enim velit a mauris.
        </layout:put>
    </layout:extends>
  3. 9

    Basato sulla stessa idea di base, come in @Sarà Hartung‘s risposta, qui è il mio magico-tag estensibile modello di motore. Esso comprende anche documentazione e un esempio 🙂

    WEB-INF/tag/blocco.tag:

    <%--
        The block tag implements a basic but useful extensible template system.
    
        A base template consists of a block tag without a 'template' attribute.
        The template body is specified in a standard jsp:body tag, which can
        contain EL, JSTL tags, nested block tags and other custom tags, but
        cannot contain scriptlets (scriptlets are allowed in the template file,
        but only outside of the body and attribute tags). Templates can be
        full-page templates, or smaller blocks of markup included within a page.
    
        The template is customizable by referencing named attributes within
        the body (via EL). Attribute values can then be set either as attributes
        of the block tag element itself (convenient for short values), or by
        using nested jsp:attribute elements (better for entire blocks of markup).
    
        Rendering a template block or extending it in a child template is then
        just a matter of invoking the block tag with the 'template' attribute set
        to the desired template name, and overriding template-specific attributes
        as necessary to customize it.
    
        Attribute values set when rendering a tag override those set in the template
        definition, which override those set in its parent template definition, etc.
        The attributes that are set in the base template are thus effectively used
        as defaults. Attributes that are not set anywhere are treated as empty.
    
        Internally, attributes are passed from child to parent via request-scope
        attributes, which are removed when rendering is complete.
    
        Here's a contrived example:
    
        ====== WEB-INF/tags/block.tag (the template engine tag)
    
        <the file you're looking at right now>
    
        ====== WEB-INF/templates/base.jsp (base template)
    
        <%@ page trimDirectiveWhitespaces="true" %>
        <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
        <t:block>
            <jsp:attribute name="title">Template Page</jsp:attribute>
            <jsp:attribute name="style">
                .footer { font-size: smaller; color: #aaa; }
                .content { margin: 2em; color: #009; }
                ${moreStyle}
            </jsp:attribute>
            <jsp:attribute name="footer">
                <div class="footer">
                    Powered by the block tag
                </div>
            </jsp:attribute>
            <jsp:body>
                <html>
                    <head>
                        <title>${title}</title>
                        <style>
                            ${style}
                        </style>
                    </head>
                    <body>
                        <h1>${title}</h1>
                        <div class="content">
                            ${content}
                        </div>
                        ${footer}
                    </body>
                </html>
            </jsp:body>
        </t:block>
    
        ====== WEB-INF/templates/history.jsp (child template)
    
        <%@ page trimDirectiveWhitespaces="true" %>
        <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
        <t:block template="base" title="History Lesson">
            <jsp:attribute name="content" trim="false">
                <p>${shooter} shot first!</p>
            </jsp:attribute>
        </t:block>
    
        ====== history-1977.jsp (a page using child template)
    
        <%@ page trimDirectiveWhitespaces="true" %>
        <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
        <t:block template="history" shooter="Han" />
    
        ====== history-1997.jsp (a page using child template)
    
        <%@ page trimDirectiveWhitespaces="true" %>
        <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
        <t:block template="history" title="Revised History Lesson">
            <jsp:attribute name="moreStyle">.revised { font-style: italic; }</jsp:attribute>
            <jsp:attribute name="shooter"><span class="revised">Greedo</span></jsp:attribute>
        </t:block>
    
    --%>
    
    <%@ tag trimDirectiveWhitespaces="true" %>
    <%@ tag import="java.util.HashSet, java.util.Map, java.util.Map.Entry" %>
    <%@ tag dynamic-attributes="dynattributes" %>
    <%@ attribute name="template" %>
    <%
        //get template name (adding default .jsp extension if it does not contain
        //any '.', and /WEB-INF/templates/prefix if it does not start with a '/')
        String template = (String)jspContext.getAttribute("template");
        if (template != null) {
            if (!template.contains("."))
                template += ".jsp";
            if (!template.startsWith("/"))
                template = "/WEB-INF/templates/" + template;
        }
        //copy dynamic attributes into request scope so they can be accessed from included template page
        //(child is processed before parent template, so only set previously undefined attributes)
        Map<String, String> dynattributes = (Map<String, String>)jspContext.getAttribute("dynattributes");
        HashSet<String> addedAttributes = new HashSet<String>();
        for (Map.Entry<String, String> e : dynattributes.entrySet()) {
            if (jspContext.getAttribute(e.getKey(), PageContext.REQUEST_SCOPE) == null) {
                jspContext.setAttribute(e.getKey(), e.getValue(), PageContext.REQUEST_SCOPE);
                addedAttributes.add(e.getKey());
            }
        }
    %>
    
    <% if (template == null) { //this is the base template itself, so render it %>
        <jsp:doBody/>
    <% } else { //this is a page using the template, so include the template instead %>
        <jsp:include page="<%= template %>" />
    <% } %>
    
    <%
        //clean up the added attributes to prevent side effect outside the current tag
        for (String key : addedAttributes) {
            jspContext.removeAttribute(key, PageContext.REQUEST_SCOPE);
        }
    %>
  4. 4

    Utilizzare piastrelle. Ha salvato la mia vita.

    Ma se non è possibile, c’è il tag, rendendola simile a php.

    Tag body non potrebbe realmente fare ciò che è necessario, a meno che non hai super semplice contenuto. Il tag body è utilizzato per definire il corpo di un elemento specificato. Date un’occhiata a questo esempio:

    <jsp:element name="${content.headerName}"   
       xmlns:jsp="http://java.sun.com/JSP/Page">    
       <jsp:attribute name="lang">${content.lang}</jsp:attribute>   
       <jsp:body>${content.body}</jsp:body> 
    </jsp:element>

    Si specifica il nome dell’elemento, tutti gli attributi dell’elemento può avere (“lang” in questo caso), e quindi il testo che va in esso-il corpo. Quindi, se

    • content.headerName = h1,
    • content.lang = fr, e
    • content.body = Heading in French

    Quindi il risultato sarebbe

    <h1 lang="fr">Heading in French</h1>
  5. 0

    aggiungere dependecys per l’uso <%@tag description=”Utente modello di Pagina” pageEncoding=”UTF-8″%>

    <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
            <dependency>
                <groupId>javax.servlet.jsp.jstl</groupId>
                <artifactId>javax.servlet.jsp.jstl-api</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
        </dependencies>
  6. 0

    So che questa risposta è venuta anni dopo il fatto, e già c’è un grande JSP risposta da Hartung, ma c’è Facelets, sono anche citati nelle risposte collegate domanda la domanda originale.

    Facelets MODO da tag di descrizione

    Facelets è basato su XML tecnologia di visualizzazione per il framework JavaServer Faces. Progettato specificamente per il JSF, Facelets è destinato ad essere un modo più semplice e più potente alternativa alla JSP visualizzazioni. Inizialmente un progetto separato, la tecnologia è stato standardizzato come parte di JSF 2.0 e Java EE 6 e ha deprecato JSP. Quasi tutti JSF 2.0 mirata alle librerie di componenti non supporto JSP più, ma solo Facelets.

    Purtroppo i migliori pianura tutorial descrizione che ho trovato era su Wikipedia e non un tutorial del sito. Infatti la sezione che descrive modelli anche lungo le linee di quello che la domanda originale era per chiedere.

    Dovuto al fatto che Java EE 6 ha deprecato JSP mi consiglia di andare con Facelets, nonostante il fatto che sembra che ci potrebbe essere di più richieste per poco o nessun guadagno sul JSP.

    • Java EE 6 non è deprecato, JSP, solo deprecato utilizzando JSP come la tecnologia di visualizzazione per il JSF.
    • Poiché in questo caso entrambi parlavano sulla tecnologia di visualizzazione, cosa c’è di male detto questo è deprecato?
    • La questione non ha nulla a che fare con il JSF. Si tratta di circa pura JSP. La tua risposta è quella di utilizzare Facelets, che è per il JSF.

Lascia un commento