You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:05:19