关于JSTL <c:set>标签(含target属性)的基础使用困惑咨询
嘿,刚接触JSTL时卡在<c:set>这类基础标签上太正常了——很多新手都会在这里混淆作用域和EL表达式的配合逻辑。咱们先从你写的代码入手,一步步梳理你可能遗漏的核心概念~
先看你当前代码的问题点
你现在用的是传统JSP脚本写法,直接在页面里写Java代码创建Map并赋值:
<%@ page import="java.util.*" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <% Map<String,Integer> mymap = new HashMap<String,Integer>(); mymap.put("name",new Integer(1)); out.println(mymap.get("name")); %> </body> </html>
这段代码本身没问题,但JSTL的核心价值就是减少页面中的Java脚本,用标签化的方式替代逻辑操作。而你现在的问题,大概率是没理清<c:set>和「JSP作用域」「EL表达式」的配合关系。
<c:set>的核心用法(对应你遗漏的基础概念)
<c:set>本质是用来在JSP中设置变量/属性,主要有三类场景,每类都对应一个基础概念:
1. 给JSP作用域设置变量
JSP有4个作用域:page(当前页面)、request(当前请求)、session(当前会话)、application(全局应用)。<c:set>可以直接在指定作用域中创建变量,替代Java里的pageContext.setAttribute()这类代码:
<!-- 在page作用域创建变量username,值为Alice --> <c:set var="username" value="Alice" scope="page" /> <!-- 用EL表达式访问变量 --> <p>用户名:${username}</p>
你可能遗漏的点:JSTL标签只能访问作用域中的对象,如果像你原来的代码那样,Map只是Java脚本里的局部变量,JSTL是拿不到的,必须把它放到某个作用域中。
2. 给Map设置键值对(对应你的代码场景)
针对你代码里的Map,用<c:set>替代mymap.put()的前提是:先把Map放到作用域中,然后用target指定Map对象,property指定键,value指定值:
<%@ page import="java.util.*" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <% // 初始化Map并放到page作用域,让JSTL能访问 Map<String,Integer> mymap = new HashMap<>(); pageContext.setAttribute("mymap", mymap); %> <!-- 用<c:set>给Map赋值,替代mymap.put("name", 1) --> <c:set target="${mymap}" property="name" value="1" /> <!-- 用EL表达式输出,替代out.println() --> <p>Map中的name值:${mymap.name}</p> </body> </html>
这里的关键是${mymap}是EL表达式,用来从作用域中获取Map对象——这也是JSTL和EL的核心配合逻辑。
3. 给JavaBean设置属性
如果你的项目里用到JavaBean(比如User类,有setName()方法),<c:set>还能直接调用setter方法赋值:
<!-- 先创建User对象并放到page作用域 --> <jsp:useBean id="user" class="com.example.User" scope="page" /> <!-- 调用user.setName("Bob") --> <c:set target="${user}" property="name" value="Bob" /> <!-- 输出user.getName()的结果 --> <p>用户姓名:${user.name}</p>
完整的无脚本改造示例
如果想彻底去掉页面里的Java脚本,可以用<jsp:useBean>创建Map,再配合<c:set>:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <!-- 创建HashMap并放到page作用域 --> <jsp:useBean id="mymap" class="java.util.HashMap" scope="page" /> <!-- 用<c:set>设置键值对 --> <c:set target="${mymap}" property="name" value="1" /> <c:set target="${mymap}" property="age" value="25" /> <!-- 直接用EL输出所有值 --> <p>name: ${mymap.name}</p> <p>age: ${mymap.age}</p> </body> </html>
总结你可能遗漏的核心概念
- JSP作用域:JSTL标签只能操作作用域中的对象,局部变量无法被访问;
- EL表达式:
${}是JSTL的“眼睛”,用来获取作用域中的变量、对象属性或Map键值; - <c:set>的多场景适配:它不止能设置简单变量,还能给Map、JavaBean赋值,本质是替代Java中的赋值逻辑。
内容的提问来源于stack exchange,提问作者user7866987

