在工作中,我的任务是将一堆HTML文件转换成一个简单的JSP项目。它完全是静态的,没有服务器端逻辑来编程。我应该提一下,我对Java完全不熟悉。JSP文件似乎可以很容易地使用常见的include和变量,就像PHP一样,但我想知道一个简单的方法来获得像模板继承(Django风格)这样的东西,或者至少能够有一个包含页眉和页脚的base.jsp文件,这样我就可以稍后插入内容。

Ben Lings似乎在他的回答中提供了一些希望: JSP模板继承 有人能解释一下如何做到这一点吗?

鉴于我没有太多时间,我认为动态路由有点多,所以我很乐意让url直接映射到.jsp文件,但我愿意听取建议。

谢谢。

编辑:我不想使用任何外部库,因为这将增加我自己和其他参与项目的人的学习曲线,而我工作的公司已经签订了这样做的合同。

另一个编辑:我不确定JSP标记是否有用,因为我的内容实际上没有任何模板变量。我需要的是一种能够做到这一点的方法:

base.html:

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

somepage.html

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

输出为:

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

我想这会给我足够多的功能去做我需要的一切。它可以通过包含来实现,但然后我需要为每个包装器设置一个顶部和底部包含,这有点混乱。


当前回答

这也可以用jsp:include实现。查德·达比在这个视频中解释得很好 https://www.youtube.com/watch?v=EWbYj0qoNHo

其他回答

使用瓷砖。它救了我的命。

但如果你不能,有include标签,使它类似于php。

body标签实际上可能不做您需要它做的事情,除非您有超级简单的内容。body标记用于定义指定元素的主体。看看这个例子:

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

您指定元素名称、元素可能具有的任何属性(在本例中为“lang”),然后是其中的文本——主体。因此,如果

内容。headerName = h1, 内容。Lang = fr,和 内容。body =法文标题

那么输出将是

<h1 lang="fr">Heading in French</h1>

我知道这个答案在几年之后才会出现,而且Will Hartung已经给出了一个很棒的JSP答案,但是还有Facelets,它们甚至在原始问题的链接问题的答案中被提到。

Facelets SO标签描述

Facelets是JavaServer Faces框架的一种基于xml的视图技术。Facelets专门为JSF设计,旨在成为基于jsp的视图的更简单、更强大的替代品。最初是一个单独的项目,该技术被标准化为JSF 2.0和Java-EE 6的一部分,并且已经弃用了JSP。几乎所有针对JSF 2.0的组件库都不再支持JSP,只支持Facelets。

遗憾的是,我在维基百科上找到了最好的教程描述,而不是教程网站。事实上,描述模板的部分甚至遵循了最初问题的要求。

由于Java-EE 6已经弃用了JSP,我建议使用Facelets,尽管它看起来可能需要更多的功能,但与JSP相比几乎没有任何好处。

正如skaffman所建议的,JSP 2.0标记文件是蜜蜂的膝盖。

让我们举个简单的例子。

将以下内容放在WEB-INF/tags/wrapper.tag中

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

现在在example.jsp页面中:

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

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

这和你想的一样。


所以,让我们把它扩展到更一般的东西。 web - inf /标签/ 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>

要使用这个:

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

这能给你带来什么?真的有很多,但还有更好的…


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>

要使用这个: (假设我们在请求中有一个用户变量)

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

但它让你喜欢在其他地方使用用户细节块。我们将重构它。 web - inf /标签/ 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/>

现在前面的例子变成:

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

JSP标记文件的美妙之处在于,它允许您标记通用标记,然后根据您的需要对其进行重构。

JSP标记文件在很大程度上取代了tile等功能,至少对我来说是这样。我发现它们更容易使用,因为唯一的结构是你给它的,没有先入为主。此外,您还可以将JSP标记文件用于其他事情(如上面的用户详细信息片段)。

这是一个类似于我所做的DisplayTag的例子,但这都是用标签文件完成的(和条纹框架,这是s: tags..)。这将产生一个行表,交替的颜色,页面导航等:

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

当然,这些标记与JSTL标记一起工作(如c:if等)。在标记文件标记体中惟一不能做的事情是添加Java scriptlet代码,但这并不是您想象的那么大的限制。如果我需要scriptlet的东西,我只需要把逻辑放到一个标记中,然后把标记放进去。一件容易的事。

标签文件可以是你想要的任何东西。在最基本的层次上,它是简单的剪切和粘贴重构。获取一个布局块,将其删除,执行一些简单的参数化,然后用标记调用替换它。

在更高的层次上,你可以做一些复杂的事情,比如我这里的这个表格标签。

我做了一个很简单的,Django风格的JSP模板继承标记库。 https://github.com/kwon37xi/jsp-template-inheritance

我认为它可以很容易地管理布局,没有学习曲线。

示例代码:

jsp:布局

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

jsp:内容

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

为<%@tag description="用户页面模板"添加依赖项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>