JSP嵌套标签出现对象无法解析变量错误,如何共享控制器传入对象?
问题描述
用JSP构建应用页面时,通过外层page标签嵌套子标签,要求所有标签访问控制器传入的同一个Map对象。当前page.tag和login.tag均定义了var属性(类型为java.util.Map),在login.jsp中从request获取variables属性赋值给var,再将var传递给两个标签,但编译时出现「var cannot be resolved to a variable」错误;移除login标签或login.tag不使用该对象时可正常运行。需要解决如何让两个标签都能使用该var对象,或提供其他实现思路。
代码片段展示
page.tag(外层简化版)
<%@ tag language="java" pageEncoding="UTF-8"%> <%@ attribute name="var" required="true" type="java.util.Map"%> <!DOCTYPE html> <html> <head> <title>${var.title}</title> ... 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(嵌套简化版)
<%@ 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>
login.jsp使用方式
<%@ 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); ...
错误信息
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
解决方案
1. 直接用EL表达式传递request属性(推荐)
去掉JSP脚本中创建var变量的代码,直接在标签属性里用EL表达式引用request中的variables对象,避免脚本变量的作用域问题:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.Map" %> <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %> <t:page var="${variables}"> <jsp:body> <t:login var="${variables}"></t:login> </jsp:body> </t:page>
2. 将变量放入pageContext,标签直接访问
在login.jsp的脚本中将var存入pageContext,标签无需定义var属性,直接通过EL访问全局变量:
- 修改login.jsp脚本:
<% Map<String,String> var = Map.of(); if (request.getAttribute("variables") != null) { var = (Map<String,String>) request.getAttribute("variables"); } pageContext.setAttribute("pageVars", var); %>
- 修改page.tag:
<%@ tag language="java" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>${pageVars.title}</title> ... 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:
<%@ tag language="java" pageEncoding="UTF-8"%> <div class="login"> <form id="loginForm"> <input type="text" name="username"> <input type="password" name="password"> <input type="hidden" name="session" value="${pageVars.session}"> ... </form> </div>
- login.jsp调用标签:
<t:page> <jsp:body> <t:login></t:login> </jsp:body> </t:page>
3. 统一全局变量命名
让控制器直接将Map存入request的固定命名属性(比如globalVars),所有标签直接使用该变量名,无需传递属性,进一步简化代码。
内容的提问来源于stack exchange,提问作者xormar
相关产品推荐
相关产品推荐

