Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid using scriptlets in my JSP page?

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>   <% } %>     &nbsp; </div>  <div class="body">   <decorator:body /> </div>  </body> </html> 

Thanks all

like image 499
Chris Avatar asked Feb 02 '10 23:02

Chris


People also ask

What is wrong in using JSP scriptlet tags?

Its not a clean design to mingle code with view logic. This is why JSP is not ideal solution. You should use templates like Velocity/Freemarker instead which does not allow mixing java code at all.

What is correct about JSP Scriptlets?

When the scripting language is set to java, a scriptlet is transformed into a Java programming language statement fragment and is inserted into the service method of the JSP page's servlet. A programming language variable created within a scriptlet is accessible from anywhere within the JSP page.

How many Scriptlets are there in JSP?

There are three main subdivisions of scripting elements in JSP. They all provide different ways to include java code in a JSP file.

Which of the following JSP tag is used for Scriptlets?

In JSP, java code can be written inside the jsp page using the scriptlet tag.


2 Answers

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:

<%@ 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>   &nbsp; </div> 

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!):

<%@ 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>   &nbsp; </div> 

It can actually be optimized more if you collect all those "hardcoded" values like events and people and link texts in a Map 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.

<jsp-config>     <jsp-property-group>         <url-pattern>*.jsp</url-pattern>         <scripting-invalid>true</scripting-invalid>     </jsp-property-group> </jsp-config> 

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.

like image 146
BalusC Avatar answered Oct 14 '22 10:10

BalusC


As an aside, is <%= request.getContextPath() %> an acceptable use of scriptlets that isn't frowned on so much?

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

<% if(request.getRequestURI().contains("/events/")) { %> 

and

${fn:contains(pageContext.request.requestURI, '/events/')  
like image 21
Thilo Avatar answered Oct 14 '22 11:10

Thilo