如何避免在 JSP 页面中使用 scriptlet?
有人告诉我,在 JSP 页面中使用 scriptlet (<%= ... %>) 并不是一个好主意。
有更多 java/jsp 经验的人可以给我一些关于如何更改此代码的指示,以便它更“最佳实践”,无论是什么?
这个JSP实际上是我的sitemesh主装饰器页面。基本上我的网页设计有一个选项卡条和一个子菜单,我希望以某种方式突出显示当前选项卡并通过查看当前请求 URI 来显示正确的子菜单。
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="<%= request.getContextPath() %>/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
<%= request.getRequestURI().contains("/events/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/events/Listing.action'>Events</a>
<a
<%= request.getRequestURI().contains("/people/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/people/Listing.action'>People</a>
</div>
<div class="submenu">
<% if(request.getRequestURI().contains("/events/")) { %>
<a href="Listing.action">List of Events</a>
|<a href="New.action">New Event</a>
<% } %>
<% if(request.getRequestURI().contains("/people/")) { %>
<a href="Listing.action">List of People</a>
|<a href="New.action">New Person</a>
<% } %>
</div>
<div class="body">
<decorator:body />
</div>
</body>
</html>
谢谢大家
I've been told that the use of scriptlets (<%= ... %>) in my JSP pages isn't such a great idea.
Can someone with a bit more java/jsp experience please give me some pointers as to how to change this code so its more 'best practice', whatever that may be?
This JSP is actually my sitemesh main decorator page. Basically my web design has a tab strip and a submenu, and i wish to somehow highlight the current tab and show the correct submenu by looking at the current request URI.
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="<%= request.getContextPath() %>/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
<%= request.getRequestURI().contains("/events/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/events/Listing.action'>Events</a>
<a
<%= request.getRequestURI().contains("/people/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/people/Listing.action'>People</a>
</div>
<div class="submenu">
<% if(request.getRequestURI().contains("/events/")) { %>
<a href="Listing.action">List of Events</a>
|<a href="New.action">New Event</a>
<% } %>
<% if(request.getRequestURI().contains("/people/")) { %>
<a href="Listing.action">List of People</a>
|<a href="New.action">New Person</a>
<% } %>
</div>
<div class="body">
<decorator:body />
</div>
</body>
</html>
Thanks all
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我认为,如果您亲眼看到它实际上可以完全无需 scriptlet 完成,那会更有帮助。
这是在 JSTL< 等帮助下进行的一对一重写/a> (只需删除
jstl-1.2.jar< /code>
在
/WEB-INF/lib
中)核心 和 functions taglib:这是一个更优化的重写,请注意,我使用
c:set
来“缓存”表达式结果以供重用,并且我使用 HTML
标签以避免将上下文路径放入每个链接中(只需使网页中的所有相对 URL 相对于它 - 没有前导斜杠!):如果您收集所有这些“硬编码”值,例如
events
和people
以及应用程序范围内Map
中的链接文本,并在每个 JSTL
显示选项卡。至于您的实际问题,您可以通过在 web 应用程序的
web.xml
中添加以下条目来禁用 scriptlet(并获取有关使用它的运行时错误) 。它可能有助于发现受监督的脚本。要了解有关 EL 的更多信息,请查看 Java EE 教程第二部分第 5 章。隐式 EL 对象,例如
${pageContext}
的描述是 这里。要了解有关 JSTL 的更多信息,请查看 Java EE 教程第二部分第 7 章。请注意,JSTL 和 EL 是两个不同的东西。 JSTL 是一个标准标签库,EL 仅支持以编程方式访问后端数据。虽然它通常在像 JSTL 这样的标签库中使用,但它也可以在模板文本中独立使用。I think it helps more if you see with your own eyes that it can actually be done entirely without scriptlets.
Here's a 1 on 1 rewrite with help of among others JSTL (just drop
jstl-1.2.jar
in/WEB-INF/lib
) core and functions taglib:Here's a more optimized rewrite, note that I used
c:set
to "cache" expression results for reuse and that I use HTML<base>
tag to avoid putting the context path in every link (just make all relative URL's in your webpage relative to it --without the leading slash!):It can actually be optimized more if you collect all those "hardcoded" values like
events
andpeople
and link texts in aMap
in the application scope and use under each the JSTL<c:forEach>
to display the tabs.As to your actual question, you can disable scriptlets (and get runtime errors about using it) by adding the following entry in webapp's
web.xml
. It may help to spot overseen scriptlets.To learn more about EL, check the Java EE tutorial part II chapter 5. Implicit EL objects, such as
${pageContext}
are described here. To learn more about JSTL, check the Java EE tutorial part II chapter 7. Note that JSTL and EL are two separate things. JSTL is a standard taglib and EL just enables to access backend data programmatically. Although it is normally used in taglibs like JSTL, it can also be used standalone in template text.这可能是一个不受欢迎的观点,但如果您所做的只是简单的条件和文本插入,那么我在使用 scriptlet 时找不到太多错误。 (注意 if)
我可能会使用 JSTL 和表达式语言,但主要是因为它可以减少打字,并且 IDE 支持可能更好(但是一个好的 JSP IDE 也可以找到丢失的右括号和类似的东西)。
但从根本上(如“将逻辑排除在模板之外”)我看不出
和之间有任何区别
This may be an unpopular opinion, but if all you do are simple conditionals and text insertions, I cannot find much fault in the use of scriptlets. (Note the if)
I'd probably use JSTL and the expression language, but mostly because it can be less typing, and IDE support may be better (but a good JSP IDE can also find missing closing brackets and stuff like that).
But fundamentally (as in "keep logic out of templates") I fail to see any difference between
and
Scriptlet 并不是世界上最糟糕的事情。一个重要的考虑因素是考虑谁将维护代码。如果网页设计人员没有太多 Java 经验,那么使用标签库可能会更好。然而,如果 Java 开发人员进行维护,那么使用 scriptlet 可能会更容易。
如果您最终使用标签库和 JSTL,那么您期望维护者也学习标签库并了解 JSTL。一些开发人员会对此感到满意,因为这是他们想要或已经拥有的技能,但对于一些只需要每隔几个月左右处理一次 JSP 的开发人员来说,使用用漂亮的语言编写的清晰编写的 scriptlet 可以减轻很多痛苦。 ,熟悉Java。
Scriptlets aren't the worst thing in the world. An important consideration is to think about who is going to be maintaining the code. If its web designers who don't have much Java experience, you are probably better off going with tag libraries. However, if Java developers are doing the maintainance, it may be easier on them to go with scriptlets.
If you end up using a tag library and JSTL, you are expecting the maintainer to also learn the tag library and know JSTL. Some developers will be fine with this as it is a skill they want or already have, but for some developers who only have to deal with JSPs every few months or so, it can be lot less painful to work with clearly written scriptlets written in nice, familiar Java.
这不是对你的问题的直接答案(已经有几个很好的答案,所以我不会尝试添加它),但你确实提到:
在我看来,关于 JSP 的最佳实践是,它应该严格用作模板引擎,仅此而已(即,其中没有业务逻辑)。正如许多人指出的那样,使用 JSTL 绝对可以帮助您实现这一目标,但即使使用 JSTL,在 JSP 中也可以轻松完成很多工作。
我个人喜欢遵循 强制严格的模型视图分离中规定的规则Terence Parr 在 JSP 中进行开发时编写的模板引擎。论文提到了模板引擎的目的(模型和视图分离),以及一个好的模板引擎的特点。它仔细研究了 JSP 并指出它不是一个好的模板引擎。毫不奇怪,JSP 基本上太强大了,并且允许开发人员做太多事情。我强烈建议您阅读本文,它将帮助您将自己限制在 JSP 的“好的”部分。
如果您只阅读该论文的一节,请阅读第 7 章,其中包括以下规则:
顺便说一句,Terence 创建了自己的模板引擎,名为 String Template,据说它在执行这些规则方面做得非常好。我对此没有个人经验,但很想在我的下一个项目中检查一下。
This isn't a direct answer to your question (and there are already several good ones, so I won't try to add to it), but you did mention:
In my opinion, best practice, with regards to JSP, is that it should be used strictly as a templating engine, and no more (i.e., no business logic in there). Using JSTL, as many pointed out, definitely helps you get there, but even with JSTL, it's easy to do to much in a JSP.
I personally like to follow the rules laid out in Enforcing Strict Model-View Separation in Templating Engines by the Terence Parr when developing in JSP. The paper mentions the purpose of templating engines (separating model and view), and characteristics of a good templating engine. It takes a good look at JSP and points out ways it's not a good templating engine. Not surprisingly, JSP is basically too powerful and allows developers to do too much. I strongly recommend reading this paper, and it'll help you restrict yourself to the "good" parts of JSP.
If you read only one section in that paper, read chapter 7, which includes the following rules:
Incidentally, Terence has created his own templating engine called String Template which supposedly does a really good job of enforcing these rules. I have no personal experience with it, but would love to check it out on my next project.
您可能想从使用标签库开始。您可以使用标准标记库 JSTL 来执行您需要执行的大多数常见操作需要 scriptlet。还有许多其他更丰富的标签库可以在 struts2 框架或 apache 中使用。
例如
将替换您的 if 语句。
You may want to start by using tag libraries. You can use the standard tag library JSTL to do most of the common things that you need scriplets for. There are many other richer tag libraries that are used like in the struts2 framework or from apache.
e.g.
would replace your if statements.
scriptlet 的首选替代方案是 JSTL 表达式语言; 这里有一个很好的概述。您需要像这样添加 taglib:
例如,JSTL 提供了一堆隐式对象,可以为您提供所需的内容;你想要的是
pageContext.request
。因此,您可以将
<%request.getRequestURI%>
替换为${pageContext.request.requestURI}
。您可以使用
标签执行条件语句。The preferred alternative to scriptlets is the JSTL expression language; here's a good overview. You'll need to add the taglib like so:
As an example, JSTL provides a bunch of implicit objects that give you the stuff you need; the one you want is
pageContext.request
.So you can replace
<%request.getRequestURI%>
with${pageContext.request.requestURI}
.You can do conditionals using
<c:if>
tags.您需要使用一些网络框架。或者至少有一些方便的标签库。或者像 FreeMarker 这样的模板引擎。
广告框架:
如果您喜欢 JSP 编码方式,那么我建议 Struts 2。
然后是面向组件的JSF。
如果您喜欢 OOP 并用 Java 编写所有内容,请尝试 Apache Wicket (我最喜欢) 或 Google 网络工具包。
You'll need to use some web framework. Or at least some convenient taglib. Or a templating enginge like FreeMarker.
Ad frameworks:
If you like JSP way of coding, then I'd suggest Struts 2.
Then there's component-oriented JSF.
If you like OOP and coding everything in Java, try Apache Wicket (my favorite) or Google Web Toolkit.