杰瑞科技汇

Java如何调用JSP变量?

JSP(JavaServer Pages)本质上是一个 Servlet,JSP 文件最终会被 Web 容器(如 Tomcat)编译成一个 Java Servlet 类,在 JSP 中定义的变量,最终会存在于这个生成的 Servlet 类中。

Java如何调用JSP变量?-图1
(图片来源网络,侵删)

根据变量定义的位置和作用域,Java 代码获取它的方式完全不同,我们主要分为以下几种情况:


获取 JSP 页面作用域(Page Scope)的变量

这种变量通常是在 JSP 的脚本片段(<% ... %>)中声明的局部变量。

JSP 代码示例 (page.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>Page Scope 示例</title>
</head>
<body>
    <%-- 在这里定义一个页面作用域的变量 --%>
    <%!
        String pageMessage = "这是一个页面作用域的变量!";
    %>
    <%-- 在另一个脚本片段中使用它 --%>
    <%
        System.out.println("在 JSP 脚本中直接访问: " + pageMessage);
    %>
    <h1>页面内容</h1>
    <p><%= pageMessage %></p> <%-- 使用表达式输出 --%>
    <%-- 我们尝试在 Java 代码中获取它 --%>
    <%
        // 这里的代码就在生成的 Servlet 的 _jspService 方法中
        // 所以可以直接访问在 <%! ... %> 中定义的成员变量
        String retrievedMessage = pageMessage;
        System.out.println("在同一个 JSP 的 _jspService 方法中获取: " + retrievedMessage);
    %>
</body>
</html>

Java 代码如何获取?

Java如何调用JSP变量?-图2
(图片来源网络,侵删)
  1. 在同一个 JSP 文件内:如上所示,如果你在一个 <% ... %> 脚本片段中,你可以直接访问在 <%! ... %> 声明的成员变量,因为它们都属于同一个 Servlet 类。
  2. 在另一个独立的 Java 类(如 Servlet)中这是不可能的,因为 pageMessage 是生成 Servlet 的一个实例成员变量,它的生命周期和当前这个 JSP 页面请求的生命周期绑定,外部类无法直接访问这个特定的 Servlet 实例的私有或受保护成员。

页面作用域的变量仅限于在 JSP 文件内部使用,无法被外部的 Java 代码直接调用。


获取 JSP 作用域(JSP Scope)的变量

这是最常见、最规范的用法,JSP 提供了四个内置的域对象(Scope Objects),用于在不同范围内存储和共享数据。

作用域 内置对象 生命周期 适用场景
Page pageContext 当前页面请求 仅在当前页面有效,极少使用。
Request request 当前 HTTP 请求 数据在同一个请求的多个组件(如 forward 的 Servlet/JSP)间共享。
Session session 用户会话 数据在用户多次请求之间共享(如登录状态、购物车)。
Application application Web 应用 数据在整个 Web 应用中所有用户间共享(如全局计数器)。

正确的工作流程是:JSP 存储数据,Java 代码(通常是 Servlet)从作用域中获取数据。

在 JSP 中设置变量到作用域

JSP 代码示例 (set_data.jsp):

Java如何调用JSP变量?-图3
(图片来源网络,侵删)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>设置作用域变量</title>
</head>
<body>
    <h1>正在设置变量...</h1>
    <%
        // 1. 设置到 Request 作用域
        String requestMsg = "Hello from Request Scope!";
        request.setAttribute("requestMessage", requestMsg);
        // 2. 设置到 Session 作用域
        String sessionMsg = "Hello from Session Scope!";
        session.setAttribute("sessionMessage", sessionMsg);
        // 3. 设置到 Application 作用域
        int appCounter = application.getAttribute("appCounter") == null ? 0 : (int)application.getAttribute("appCounter");
        application.setAttribute("appCounter", ++appCounter);
    %>
    <p>已设置变量,请点击下面的链接跳转到 Servlet 查看。</p>
    <a href="GetServlet">跳转到 Servlet 获取数据</a>
</body>
</html>

在 Java Servlet 中获取变量

Java 代码示例 (GetServlet.java):

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/GetServlet") // 映射 URL
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 从 Request 作用域获取
        // 使用与 JSP 中 setAttribute 时相同的 key
        String requestMessage = (String) request.getAttribute("requestMessage");
        // 2. 从 Session 作用域获取
        // 注意:需要先获取 session 对象
        String sessionMessage = (String) request.getSession().getAttribute("sessionMessage");
        // 3. 从 Application 作用域获取
        Integer appCounter = (Integer) getServletContext().getAttribute("appCounter");
        // 打印到控制台
        System.out.println("--- 从 Servlet 中获取的变量 ---");
        System.out.println("Request Message: " + requestMessage);
        System.out.println("Session Message: " + sessionMessage);
        System.out.println("Application Counter: " + appCounter);
        // 也可以将获取到的数据存入 request,forward 到一个 JSP 页面进行显示
        request.setAttribute("retrievedRequestMsg", requestMessage);
        request.getRequestDispatcher("display_data.jsp").forward(request, response);
    }
}

显示数据的 JSP (display_data.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>显示从 Servlet 获取的数据</title>
</head>
<body>
    <h1>从 Servlet 获取并显示的数据</h1>
    <%-- 从 request 作用域中取出数据并显示 --%>
    <p>从 Request 作用域获取的消息是: <strong><%= request.getAttribute("retrievedRequestMsg") %></strong></p>
    <%-- 也可以直接显示从 Servlet forward 过来的所有 request 数据 --%>
    <p>原始的 Request 消息 (通过EL表达式): <strong>${requestMessage}</strong></p>
</body>
</html>

获取 JSP EL 表达式中的变量

EL (Expression Language) 如 ${variable} 是 JSP 2.0 之后推荐的表达式写法,它通常从作用域中查找变量。

JSP 代码示例 (el_example.jsp):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<html>
<head>EL 变量示例</title>
</head>
<body>
    <%
        // 在 request 作用域中存入一个 List
        List<String> names = List.of("Alice", "Bob", "Charlie");
        request.setAttribute("userList", names);
    %>
    <h1>使用 EL 表达式访问变量</h1>
    <p>用户列表: ${userList}</p>
    <p>第一个用户: ${userList[0]}</p>
</body>
</html>

Java 代码如何获取?

EL 表达式 ${userList} 本质上就是 pageContext.findAttribute("userList") 的简写,它会在 Page -> Request -> Session -> Application 作用域中依次查找名为 "userList" 的属性。

获取 EL 变量的方式和场景二完全一样:你只需要知道 EL 表达式使用的 key(这里是 "userList"),然后在 Java 代码中从相应的作用域(通常是 request.getAttribute("userList"))中获取即可。


总结与最佳实践

变量类型 位置 Java 代码如何获取 推荐用法
页面作用域变量 <%! %> 无法被外部 Java 代码调用,仅限 JSP 内部。 尽量避免使用,逻辑应放在 Java 类中。
作用域变量 request/session/application.setAttribute() 通过 request.getAttribute(), session.getAttribute(), application.getAttribute() 使用相同的 key 来获取。 这是标准做法,JSP 负责展示数据,Servlet/Java 类负责处理业务逻辑和设置数据。
EL 变量 ${key} 和作用域变量一样,通过 key 从作用域中获取。 JSP 2.0+ 的首选,用于简化页面数据输出。

核心思想:分层架构

现代 Java Web 开发遵循 MVC(Model-View-Controller)模式:

  • Model (模型): JavaBean/POJO,代表数据。
  • View (视图): JSP/HTML,负责展示数据。
  • Controller (控制器): Servlet,负责接收请求、调用业务逻辑、处理数据,然后将数据存入作用域,并选择合适的视图进行响应。

在这种模式下,Java 代码(Controller)不会去“调用” JSP 的变量,而是将数据“放入”作用域,然后由 JSP(View)从作用域中“取出”并显示,这实现了数据和视图的解耦,是项目可维护性的关键。

分享:
扫描分享到社交APP
上一篇
下一篇