如何避免在JSP页面中使用scriptlet?
我被告知在我的JSP页面中使用scriptlets(<%= ...%>)并不是一个好主意。
如果有人有更多的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>
谢谢大家
如果你亲眼看到它实际上可以完全没有 scriptlet的话,我认为它会更有帮助。
这里有jstl-1.2.jar
重写,其中包括JSTL(只需在/WEB-INF/lib
删除jstl-1.2.jar
)核心和函数taglib:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="${pageContext.request.contextPath}/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
${fn:contains(pageContext.request.requestURI, '/events/') ? 'class="selected"' : ''}
href="${pageContext.request.contextPath}/events/Listing.action">Events</a>
<a
${fn:contains(pageContext.request.requestURI, '/people/') ? 'class="selected"' : ''}
href="${pageContext.request.contextPath}/people/Listing.action">People</a>
</div>
<div class="submenu">
<c:if test="${fn:contains(pageContext.request.requestURI, '/events/')}">
<a href="Listing.action">List of Events</a>
|<a href="New.action">New Event</a>
</c:if>
<c:if test="${fn:contains(pageContext.request.requestURI, '/people/')}">
<a href="Listing.action">List of People</a>
|<a href="New.action">New Person</a>
</c:if>
</div>
这里有一个更优化的重写,请注意,我使用c:set
为“缓存”表达式结果以供重用,并且我使用HTML <base>
标记来避免将上下文路径放在每个链接中(只需使网页中的所有相对URL相对于它 - 没有领先的斜线!):
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<c:set var="isEvents" value="${fn:contains(pageContext.request.requestURI, '/events/')}" />
<c:set var="isPeople" value="${fn:contains(pageContext.request.requestURI, '/people/')}" />
<html>
<head>
<title>My Events - <decorator:title /></title>
<base href="${pageContext.request.contextPath}">
<link href="assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a ${isEvents ? 'class="selected"' : ''} href="events/Listing.action">Events</a>
<a ${isPeople ? 'class="selected"' : ''} href="people/Listing.action">People</a>
</div>
<div class="submenu">
<c:if test="${isEvents}">
<a href="Listing.action">List of Events</a>|<a href="New.action">New Event</a>
</c:if>
<c:if test="${isPeople}">
<a href="Listing.action">List of People</a>|<a href="New.action">New Person</a>
</c:if>
</div>
如果您收集所有“硬编码”值(如events
和people
以及链接文本到应用程序范围中的Map
中并在每个JSTL <c:forEach>
以显示选项卡,则实际上可以进行优化。
至于你的实际问题,你可以通过在webapp的web.xml
添加以下条目来禁用scriptlet(并获得有关使用它的运行时错误)。 这可能有助于发现监督脚本。
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
要了解关于EL的更多信息,请查看Java EE教程第II部分第5章。隐式EL对象,如${pageContext}
在这里描述。 要了解关于JSTL的更多信息,请查阅Java EE教程第二部分第7章。请注意,JSTL和EL是两个独立的东西。 JSTL是一个标准的taglib,EL只是允许以编程方式访问后端数据。 虽然它通常用于像JSTL这样的taglib,但它也可以在模板文本中单独使用。
另外, <%= request.getContextPath() %>
可接受的scriptlet的使用是不会皱眉的吗?
这可能是一个不受欢迎的观点,但是如果你所做的只是简单的条件和文本插入,我在使用scriptlet时就找不到太多的错误。 (注意如果)
我可能会使用JSTL和表达式语言,但主要是因为它可能更少打字,并且IDE支持可能会更好(但一个好的JSP IDE也可以找到缺少的右括号和类似的东西)。
但从根本上(如“保持模板逻辑”),我没有看到任何区别
<% if(request.getRequestURI().contains("/events/")) { %>
和
${fn:contains(pageContext.request.requestURI, '/events/')
这不是对你的问题的直接回答(并且已经有好几个很好的问题,所以我不会试图添加它),但是你提到了:
如果有人有更多的java / jsp经验,请给我一些关于如何更改此代码的指示,以便更好地实现它,无论这可能是什么?
在我看来,关于JSP的最佳实践是它应该被严格地用作模板引擎,并且不会有更多(即没有业务逻辑)。 正如许多人指出的那样,使用JSTL确实可以帮助您达到目标,但即使使用JSTL,在JSP中执行操作也很容易。
我个人喜欢遵循在JSP中开发时由Terence Parr实施严格的模板引擎中的模型 - 视图分离中规定的规则。 本文提到模板引擎的目的(分离模型和视图)以及良好模板引擎的特性。 它仔细研究了JSP并指出了它不是一个好的模板引擎。 毫不奇怪,JSP基本上太强大了,并且允许开发人员做太多。 我强烈建议阅读本文,它将帮助您将自己限制在JSP的“良好”部分。
如果您只阅读该论文的一节,请阅读第7章,其中包含以下规则:
顺便提一句,特伦斯创建了自己的模板引擎,称为字符串模板,该模板据说在执行这些规则方面确实做得很好。 我没有亲身体验过它,但很想在我的下一个项目中查看它。
链接地址: http://www.djcxy.com/p/13359.html上一篇: How to avoid using scriptlets in my JSP page?
下一篇: Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern