views:

53

answers:

2

My site has a nav menu that is dynamically built as a separate JSP, and included in most pages via <jsp:include />. The contents and styling of the menu are determined by which pages the user does and doesn't have access to.

The set of accessible pages is retrieved from the database when a user logs in, and not during the course of a session. So, there's really no need to re-evaluate the nav menu code every time the user requests a page. Is there an easy way to generate the markup from the JSP only once per session, and cache/reuse it during the session?

+1  A: 

Here's a JSP Tag File that should do what you want, untested.

<%@tag description="Caches the named content once per session" pageEncoding="UTF-8"%>

<%@attribute name="name"%>

<%
String value = (String)request.getSession().getAttribute(name);

if (value == null) {
%>
<jsp:doBody var="jspBody"/>
<%
    value = jspContext.getAttribute("jspBody", PageContext.PAGE_SCOPE);
    request.getSession().setAttribute(name, value);
}
jspContext.setAttribute("value", value);
%>
${value}

To use it you'd do something like:

<t:doonce name="navigation">
    <jsp:include page="nav.jsp"/>
</t:doonce>
Will Hartung
Awesome! Will try this Monday.
Matt Ball
+3  A: 

A similar approach, but using JSTL rather than scriptlet code:

<c:if test="${empty menuContents"}>
  <c:set var="menuContents" scope="session">
    Render the menu here...
  </c:set>
</c:if>
<c:out value="${menuContents}" escapeXml="false"/>
evnafets
+1: Everything is better than scriptlets.
BalusC

related questions