Des astuces JSP pour rendre les temples plus faciles?

au travail j'ai été chargé de transformer un tas de fichiers HTML en un simple projet JSP . C'est vraiment statique, pas de serverside logique de programme. Je dois mentionner que je suis complètement nouveau à Java. Les fichiers JSP semblent faciliter le travail avec des inclusions et variables communes, un peu comme PHP , mais j'aimerais savoir un moyen simple d'obtenir quelque chose comme un héritage de modèle ( Django style) ou au moins être capable d'avoir une base.fichier jsp contenant l'en-tête et le pied de page, pour que je puisse insérer du contenu plus tard.

Ben Lings semble offrir un peu d'espoir dans sa réponse ici: héritage modèle JSP Quelqu'un peut m'expliquer comment faire?

étant donné que je n'ai pas beaucoup de temps, je pense que le routage dynamique est un peu trop, donc je suis heureux de juste avoir des URLs directement sur les fichiers .jsp , mais je suis ouvert à la suggestion.

Grâce.

edit: je ne veux pas utiliser toutes les bibliothèques externes, car il permettrait d'augmenter la courbe d'apprentissage pour moi et les autres qui travaillent sur le projet, et la société où je travaille a été mandaté pour ce faire.

un autre edit: Je ne suis pas sûr si JSP tags sera utile parce que mon contenu n'a pas vraiment de variables de modèle. Ce dont j'ai besoin, c'est d'un moyen d'être capable de faire ceci:

base.html:

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

somepage.html

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

avec la sortie étant:

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

je pense que cela me donnerait assez de polyvalence pour faire tout ce dont j'ai besoin. Cela pourrait être réalisé avec includes mais alors j'aurais besoin d'un dessus et d'un dessous pour chaque emballage, ce qui est un peu salissant.

289
demandé sur Community 2009-08-19 00:16:27

4 réponses

comme skaffman suggéré , JSP 2.0 Tag Files sont les genoux de l'abeille.

prenons votre exemple simple.

mettre ce qui suit dans WEB-INF/tags/wrapper.tag

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

maintenant dans votre example.jsp page:

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

<t:wrapper>
    <h1>Welcome</h1>
</t:wrapper>

qui fait exactement ce que vous pensez qu'il fait.


donc, nous allons développer sur que quelque chose d'un peu plus général. 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>

pour utiliser ceci:

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

Qu'est-ce que ça vous rapporte? Vraiment beaucoup de choses, mais c'est encore mieux...


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>

pour utiliser ce: (supposons que nous ayons une variable user dans la requête)

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

cet utilisateur détail bloc dans d'autres endroits. Donc, nous allons à refactoriser. 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/>

Maintenant l'exemple précédent devient:

<%@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 beauté des fichiers de Tag JSP est qu'il vous permet essentiellement tag markup générique et ensuite le remanier au contenu de votre cœur.

JSP Tag Files ont presque usurpé des choses comme Tiles etc. au moins pour moi. Je les trouve beaucoup plus faciles à utilisation comme la seule structure de ce que vous lui donnez, rien de préconçu. De plus, vous pouvez utiliser les fichiers de balise JSP pour d'autres choses (comme le fragment de détails utilisateur ci-dessus).

voici un exemple qui est similaire à DisplayTag que j'ai fait, mais tout est fait avec des fichiers de balises (et le Stripes framework, c'est le S: tags..). Il en résulte un tableau de lignes, alternant les couleurs, la navigation de page, etc:

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

bien sûr, les tags fonctionnent avec le JSTL tags (comme c:if , etc.). La seule chose que vous ne pouvez pas faire dans le corps d'une étiquette de fichier est d'ajouter du code Java scriptlet, mais ce n'est pas une limitation aussi grande que vous pourriez le penser. Si j'ai besoin de scriptlet, je mets juste la logique dans une balise et je laisse tomber la balise. Facile.

ainsi, les fichiers d'étiquettes peuvent être à peu près ce que vous voulez qu'ils soient. Au niveau le plus basique, c'est simple couper et coller refactoring. Prenez un morceau de la mise en page, coupez-le, faites un peu paramétrage simple, et le remplacer par une invocation d'étiquette.

à un niveau plus élevé, vous pouvez faire des choses sophistiquées comme cette étiquette de table que j'ai ici.

649
répondu Will Hartung 2017-05-23 12:26:07

j'ai fait assez facile, Django style JSP Template Heritage tag library. https://github.com/kwon37xi/jsp-template-inheritance

je pense qu'il est facile de gérer des mises en page sans courbe d'apprentissage.

exemple de code:

de base.jsp : mise en page

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

view.jsp : le contenu de la

<%@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>
21
répondu KwonNam 2013-09-13 17:57:33

basé sur la même idée de base que dans @Will Hartung 'S réponse, voici ma magie une étiquette moteur de gabarit extensible. Il inclut même la documentation et un exemple: -)

WEB-INF/tags / block.étiquette:

<%--
    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);
    }
%>
8
répondu amichair 2017-05-23 12:34:29

Utiliser tuiles . Il m'a sauvé la vie.

mais si vous ne pouvez pas, il y a le include tag , ce qui le rend similaire à php.

l'étiquette de corps pourrait ne pas réellement faire ce que vous avez besoin d'elle, à moins que vous ayez le contenu super simple. Le corps de la balise est utilisée pour définir le corps d'un élément spécifié. Jetez un oeil à cet exemple :

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

vous spécifiez le nom de l'élément, les attributs de l'élément ("lang" dans ce cas), et puis le texte qui va dans--le corps. Alors si

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

alors la sortie serait

<h1 lang="fr">Heading in French</h1>
4
répondu geowa4 2009-08-20 12:28:10