I am trying to build app pages via JSP, using nested tags within an outer tag ("page"). All of the tags need access to the same object, which is passed in from the controller. But I can't find out how to use the same object as attribute to a tag from within another tag.
page.tag (outer, simplified):
<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ attribute name="var" required="true" type="java.util.Map"%>
<!DOCTYPE html>
<html>
<head>
<title>${var.title}</var>
... some shared headers ...
</head>
<body>
... some shared body elements, navigation etc. ...
<jsp:doBody></jsp:doBody>
... more shared body elements, footer etc. ...
</body>
</html>
login.tag (nested, simplified):
<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ attribute name="var" required="true" type="java.util.Map"%>
<div class="login">
<form id="loginForm">
<input type="text" name="username">
<input type="password" name="password">
<input type="hidden" name="session" value="${var.session}">
...
</form>
</div>
Used in login.jsp like this:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"
import="java.util.Map"
%>
<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
<%! @SuppressWarnings("unchecked") %>
<%
Map<String,String> var = Map.of();
if (request.getAttribute("variables") != null) {
var = (Map<String,String>) request.getAttribute("variables");
}
%>
<t:page var="<%= var %>">
<jsp:body>
<t:login var="<%= var %>"></t:login>
</jsp:body>
</t:page>
Controller.java:
...
Map<String,String> var = Map.of("title", "Page title", "session", "1234567890");
request.setAttribute("variables", var);
...
I get the following error message:
Unable to compile class for JSP: An error occurred at line: [203] in the generated java file: [/var/lib/tomcat9/work/Catalina/app-name/org/apache/jsp/WEB_002dINF/jsp/login_jsp.java] var cannot be resolved to a variable
Without the <t:login>
, or if I put only simple html into login.tag
that doesn't need any objects, it works (i.e. var
is visible in page.tag
).
Is there a way to use var
in both page.tag
and login.tag
? Or am I looking at this the wrong way?
Thanks for any pointers!
You should use attribute
in tags to pass a variable.
In tag:
<%@ attribute name="var" required="true" type="java.util.Map" rtexprvalue="true"%>
In JSP:
<t:page var="${variables}">
<jsp:body>
<t:login var="${variables}"></t:login>
</jsp:body>
</t:page>
For details: Declaring Tag Attributes for Tag Handlers