有人告诉我,在我的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>
谢谢大家
我认为,如果您亲眼看到它实际上完全可以 不用 scriptlet 来完成,那么它会有所帮助。
这里有一个1对1重写与在其他的帮助JSTL(刚落jstl-1.2.jar于/WEB- INF/lib)核心和功能的taglib:
jstl-1.2.jar
/WEB- INF/lib
<%@ 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都与之相对-不用前导削减!):
c:set
<base>
<%@ 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>以显示选项卡,则实际上可以进一步优化。
events
people
Map
<c:forEach>
对于您的 实际 问题,您可以通过在webapp的中添加以下条目来 禁用 脚本(并获得有关使用脚本的运行时错误)web.xml。可能会发现被监督的脚本。
web.xml
<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group> </jsp-config>
要了解有关EL的更多信息,请查看Java EE教程第二部分第5章。隐EL对象,例如${pageContext}被描述在这里。要了解有关JSTL的更多信息,请查看Java EE教程第二部分第7章。注意,JSTL和EL是两个独立的东西。JSTL是 标准的taglib, 而EL仅允许以编程方式访问后端数据。尽管它通常在JSTL之类的标记库中使用,但也可以在模板文本中独立使用。
${pageContext}