为啥要使用模板引擎? jsp 包括和 jstl vs tile、freemarker、velocity、sitemesh

Posted

技术标签:

【中文标题】为啥要使用模板引擎? jsp 包括和 jstl vs tile、freemarker、velocity、sitemesh【英文标题】:Why would I use a templating engine? jsp include and jstl vs tiles, freemarker, velocity, sitemesh为什么要使用模板引擎? jsp 包括和 jstl vs tile、freemarker、velocity、sitemesh 【发布时间】:2011-03-11 06:14:19 【问题描述】:

我即将选择组织视图的方式(使用 spring-mvc,但这并不重要)

据我所知,有 6 个选项(尽管它们不是相互排斥的):

瓷砖 站点网格 Freemarker 速度 <jsp:include> <%@ include file="..">

TilesSitemesh可以分组; FreemarkerVelocity 也可以。每个组中使用哪一个不是这个讨论的问题,有足够的问题和讨论。

This is an interesting read,但无法说服我使用磁贴。

我的问题是 - 这些框架提供了哪些无法通过 <@ include file=".."> 和 JSTL 正确完成的功能。要点(部分摘自文章):

    包括部分页面,如页眉和页脚 - 没有区别:

    <%@ include file="header.jsp" %>
    

    <tiles:insert page="header.jsp" />
    

    在标题中定义参数 - 如标题、元标记等。这非常重要,尤其是从 SEO 的角度来看。使用模板选项,您可以简单地定义每个页面应定义的占位符。但是,您可以在带有 JSTL 的 jsp 中使用 &lt;c:set&gt;(在包含页面中)和 &lt;c:out&gt;(在包含页面中)

    布局重组 - 如果您想将面包屑移动到菜单上方,或者将登录框移动到另一个侧面板上方。如果页面包含(使用 jsp)没有很好地组织,在这种情况下您可能需要更改每个页面。但是如果你的布局不是太复杂,把常用的东西放在页眉/页脚里,那就没什么好担心的了。

    通用组件和特定内容之间的耦合 - 我没有发现这个问题。如果您想重复使用某些片段,请将其移动到不包含任何页眉/页脚的页面,并在需要的地方包含它。

    效率 - &lt;%@ include file="file.jsp" %&gt; 比其他任何东西都更有效,因为它只编译一次。所有其他选项都被解析/执行了很多次。

    复杂性 - 所有非 jsp 解决方案都需要额外的 xml 文件、额外的包含、预处理器配置等。这既是一条学习曲线,又会引入更多潜在的故障点。此外,它使支持和更改变得更加乏味 - 您必须检查许多文件/配置才能了解正在发生的事情。

    占位符 - velocity/freemarker 提供的不仅仅是 JSTL 吗?在 JSTL 中放置占位符,并使用模型(由控制器放置在请求或会话范围内)来填充这些占位符。

所以,请说服我应该使用上述任何框架来代替/除了纯 JSP。

【问题讨论】:

我不确定如何比较它们,因为我使用 Stripes 布局模板已经有一段时间了,我发现它比普通的 JSP 好多 .我确实使用了一些 jsp:include 调用,但这些通常是相当特殊的情况。布局模板机制是一个非常方便和强大的工具。 是的,听说都是“方便又强大”,但没见过。我所看到的是不必要的复杂性和成堆的配置文件。 (我不是专门谈论条纹,而是总体而言) 另见***.com/questions/610062/… 我相信 jsp:include 非常有效 - 它编译为从包含 servlet 到包含的方法调用。与@include 相比,它生成的代码更少,甚至可以通过缓存效果提高性能。 StringTemplate 开发人员提出了我见过的最好的论点,这与rule of least power 非常相似 【参考方案1】:

Velocity 的一些参数(我没有使用过 Freemarker):

有可能在网络环境之外重复使用模板,例如在发送电子邮件时 Velocity 的模板语言语法比 JSP EL 或标记库简单 将视图逻辑与任何其他类型的逻辑严格分离 - 无法选择使用 scriptlet 标记和在模板中做讨厌的事情。

占位符——velocity/freemaker 提供的不仅仅是 JSTL 吗?在 JSTL 中放置占位符,并使用模型(由控制器放置在请求或会话范围内)来填充这些占位符。

是的,references 确实是 VTL 的核心:

<b>Hello $username!</b>

#if($listFromModel.size() > 1)
    You have many entries!
#end

效率 - &lt;%@ include file="file.jsp" %&gt; 比其他任何东西都更有效,因为它只编译一次。所有其他选项都被多次解析/执行。

不太确定我是否同意或理解这一点。 Velocity 有一个缓存模板的选项,这意味着它们被解析成的抽象语法树将被缓存而不是每次都从磁盘读取。无论哪种方式(我也没有确切的数字),Velocity 对我来说总是快速

布局重组 - 如果您想将面包屑导航移动到菜单上方,或者将登录框移动到另一个侧面板上方。如果页面包含(使用 jsp)没有很好地组织,在这种情况下您可能需要更改每个页面。但如果你的布局不是太复杂,把常用的东西放在页眉/页脚,那就没什么好担心的了。

不同之处在于,使用 JSP 方法,您不会在每个使用相同页眉/页脚的 JSP 文件中重新组织此布局吗? Tiles 和 SiteMesh 允许您指定一个基本布局页面(JSP、Velocity 模板等 - 两者都是 JSP 框架的核心),您可以在其中指定任何您想要的内容,然后只需委托给主要内容的“内容”片段/模板.这意味着只有一个文件可以将标题移入。

【讨论】:

您给出的速度示例可以使用 JSTL 轻松完成。关于效率点,我的意思是 jsps 被编译为 servlet,并且没有任何东西被解析。但是缓存模板也是一个很好的解决方案,是的。至于重组 - 不,我通常以某种方式形成包含,我只需要修改包含,而不是“包含”。也许在更复杂的情况下这是不可能的。 除了在 Web 上下文之外重用模板之外,Velocity 还可以让您在呈现给客户端之前轻松抓取呈现的网页。当您希望将站点生成为 html 文件时,它很有用。使用 JSP - 没有简单的解决方案。这是我们从 JSP 切换到 Velocity 的主要原因。关于速度——我做了一些基准测试,Velocity 渲染页面的速度正好比 JSP 快 2 倍。所以速度不是问题。现在在 Velocity 工作了几年后,我再也不会回到 JSP 上了。它更简单、更轻、更清洁。 @serg555 你有没有在任何地方发布过这些基准?我很想看到更多关于这方面的数据。我也很想看看你是如何执行基准测试的。我认为这对于其他思考相同“速度与 JSP 与其他引擎”问题的人来说是一个很好的信息。 我没有发布结果。只是我从我们的网站转换了几个页面并测量了之前和之后的渲染时间。没什么太科学的:) @serg555 jsp 的平台/servlet 容器/版本是什么?【参考方案2】:

jsp:includeTiles/Sitemesh/etc 之间的选择是开发人员一直面临的简单性和功能性之间的选择。当然,如果您只有几个文件或不希望您的布局经常更改,那么只需使用 jstljsp:include

但是应用程序有一种渐进式增长的方式,并且很难证明“停止新的开发和改造磁贴(或其他一些解决方案)以便我们可以更轻松地解决未来的问题”,如果您一开始不使用复杂的解决方案,这是必需的。

如果您确定您的应用程序将始终保持简单,或者您可以设置一些应用程序复杂性基准,之后您将集成更复杂的解决方案之一,那么我建议您不要使用磁贴/等。否则,从一开始就使用它。

【讨论】:

【参考方案3】:

我不会说服您使用其他技术。据我所知,如果 JSP 适合他们,每个人都应该坚持使用它。

我主要使用 Spring MVC,我发现 JSP 2+ 与 SiteMesh 结合是完美的搭配。

SiteMesh 2/3

提供应用于视图的装饰器,主要类似于其他模板引擎中的继承工作。现在没有这样的功能是无法想象的。

JSP 2+

那些声称 JSP 将难以避免模板中的 Java 代码的人是假的。您只是不应该这样做,并且使用此版本没有必要这样做。版本 2 支持使用 EL 调用方法,这与以前的版本相比是一个很大的优势。

使用 JSTL 标签,您的代码仍然看起来像 HTML,因此不那么尴尬。 Spring通过taglibs打包了很多对JSP的支持,非常强大。

标签库也很容易扩展,因此自定义您自己的环境是一件轻而易举的事。

【讨论】:

我认为 SiteMesh 没有任何好处。 Jsp 标签提供与 SiteMesh 相同的装饰功能,但具有更大的灵活性,更少的脆弱设置,而且我推测效率也会更高,因为不涉及后处理解析。【参考方案4】:

反对使用 JSP 的 facelets(不在您的列表中,但我会提到它)的最佳论点之一是编译与解释器集成,而不是委托给 JSP 编译器。这意味着我在 JSF 1.1 中遇到的最烦人的事情之一——在保存更改以便运行时引擎发现更改时必须更改周围 JSF 标记上的 id 属性——消失了,给出了保存——在编辑器中,在浏览器中重新加载循环,以及更好的错误消息。

【讨论】:

是的,JSF facelets 是 解决方案,因为它与解释器紧密集成。但这里不是这样:) 我只是提到了它,以防它们中的任何一个具有相同的功能 - 这对我来说将是一个决定性的功能。【参考方案5】:

一个好的视图技术可以消除大多数和最烦人的 if/switch/条件语句,而简单的 include 则不能。使用“复杂”视图技术会产生“简单”应用程序。

【讨论】:

【参考方案6】:

您没有提供有关特定应用程序的信息。例如,我不使用 JSP 有几个原因:

在 JSP 模板中使用 Java 代码是不可避免的,因此你打破了纯视图的概念,结果你将难以在多个地方维护代码作为视图和控制器

JSP 自动创建建立会话的 JSP 上下文。我可能想避免它,但是如果您的应用程序总是使用会话,那对您来说可能不是问题

JSP需要编译,如果目标系统没有Java编译器,任何小的调整都需要使用其他系统然后重新部署

最小的JSP引擎大约是500k字节码加上JSTL,所以可能不适合嵌入式系统

模板引擎可以生成同一模型的不同内容类型,比如 JSON 负载、网页、电子邮件正文、CSV 等。

非 Java 程序员可能难以使用 JSP 模板,而非技术人员在修改常规模板时从未遇到过困难。

我很久以前就问过同样的问题,最后写了我的框架(肯定是基于模板引擎的),它没有我在其他解决方案中看到的所有缺点。不用说它大约是 100k 的字节码。

【讨论】:

【参考方案7】:

我意识到这是一个聪明的答案,但事实是,如果您没有看到在当前项目中使用模板而不是代码有任何优势,这可能是因为在您当前的项目中,没有一个也没有。

其中一部分与规模有关。您可能会认为包含与我们说的站点网格一样强大,这当然是正确的,至少对于少数页面(我会说可能大约 100 个),但是如果您有数千个页面,它开始变得难以管理。 (所以对于 eBay 来说没有必要,对于 Salesforce 来说可能是)

此外,正如之前提到的,freemarker 和velocity 不是特定于servlet 的。您可以将它们用于任何事情(邮件模板、离线文档等)。您不需要 Servlet 容器即可使用 freemarker 或 velocity。

最后,您的第 5 点只是部分正确。如果它还没有被访问,它会在每次被访问时被编译。这意味着每当您更改某些内容时,您需要记住删除您的 servlet 容器的“工作”目录,以便它重新编译 JSP。这对于模板引擎来说是不必要的。

TL;DR 编写模板引擎是为了解决 JSP + JSTL 的一些(感知的或实际的)缺点。是否应该使用它们完全取决于您的需求和项目的规模。

【讨论】:

以上是关于为啥要使用模板引擎? jsp 包括和 jstl vs tile、freemarker、velocity、sitemesh的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot11 Web开发 Part2 模板引擎

Thymeleaf模板引擎学习

为啥要使用 JSTL?当我们在 JSP 文件中使用带有连接字符串的数据库连接来获取从 servlet 发送的数据时会有啥危害[重复]

Spring Boot 整合模板引擎 Freemakerthymeleaf

Spring Boot 2.0 使用模板引擎返回JSP页面实战

SpringBoot整合Thymeleaf-基于SpringBoot2.X版本