杰瑞科技汇

JSP如何调用Java方法并正确传参?

在 JSP 中调用 Java 代码,本质上是在 Web 表现层(JSP)与业务逻辑层/数据访问层(Java)之间进行通信,虽然不推荐在 JSP 中直接写复杂的 Java 代码,但理解其实现方式对于维护旧项目或理解 MVC 模式至关重要。

JSP如何调用Java方法并正确传参?-图1
(图片来源网络,侵删)

以下是三种主要的方法,从最不推荐到最推荐的顺序排列。


在 JSP 中直接嵌入 Java 代码(不推荐)

这是最原始、最直接的方法,通过 JSP 的脚本元素(Scriptlets)将 Java 代码直接写在 JSP 页面中。

脚本片段

使用 <% ... %> 标签可以编写任意有效的 Java 代码片段。

示例:

JSP如何调用Java方法并正确传参?-图2
(图片来源网络,侵删)

假设我们有一个 UserService 类,它有一个 getUserNameById(int id) 方法。

UserService.java

public class UserService {
    public String getUserNameById(int id) {
        // 模拟从数据库或服务获取用户名
        if (id == 1) {
            return "张三";
        } else if (id == 2) {
            return "李四";
        }
        return "未知用户";
    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>直接调用Java方法</title>
</head>
<body>
    <h1>用户列表</h1>
    <ul>
        <li>用户ID为1的用户是: 
            <%
                // 1. 创建Java对象实例
                UserService userService = new UserService();
                // 2. 调用Java方法
                String name1 = userService.getUserNameById(1);
                // 3. 使用表达式输出结果
                out.print(name1);
            %>
        </li>
        <li>用户ID为2的用户是: <%= new UserService().getUserNameById(2) %></li>
    </ul>
</body>
</html>

特点:

JSP如何调用Java方法并正确传参?-图3
(图片来源网络,侵删)
  • 优点:简单直观,适合快速原型开发或小型脚本。
  • 缺点
    • 严重违反 MVC 原则:JSP 既负责视图展示,又负责业务逻辑处理,导致代码混乱难以维护。
    • 代码可重用性差:Java 代码被硬编码在 JSP 中,无法在其他页面或模块中复用。
    • 测试困难:无法对 JSP 中的 Java 代码进行单元测试。
    • 可读性差:大量的 Java 代码会使 JSP 页面变得臃肿,前端开发者难以理解。

使用 JSP 标准动作(<jsp:useBean>, <jsp:getProperty>, <jsp:setProperty>

这种方法比直接嵌入脚本要好一些,它通过 JSP 标准动作来操作 JavaBean 对象。

<jsp:useBean>

用于在 JSP 页面中创建或获取一个 JavaBean 实例。

  • id:给 Bean 实例起一个名字,后续通过这个名字引用它。
  • scope:Bean 的作用域,可选 page, request, session, application
  • class:Bean 的完整类名。

<jsp:getProperty>

获取 Bean 的属性值并输出到页面上,它要求 Bean 必须有对应的 getter 方法。

<jsp:setProperty>

设置 Bean 的属性值,它要求 Bean 必须有对应的 setter 方法。

示例:

User.java (一个标准的 JavaBean)

public class User {
    private int id;
    private String name;
    // 必须要有无参构造函数
    public User() {
    }
    // Getter 和 Setter 方法
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

displayUser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>使用JSP动作调用Java方法</title>
</head>
<body>
    <h1>用户信息</h1>
    <jsp:useBean id="user" class="com.example.User" scope="page"/>
    <jsp:setProperty name="user" property="id" value="101"/>
    <jsp:setProperty name="user" property="name" value="王五"/>
    <p>用户ID: <jsp:getProperty name="user" property="id"/></p>
    <p>用户姓名: <jsp:getProperty name="user" property="name"/></p>
    <%-- 如果方法不是标准的 getter/setter,仍然需要脚本片段 --%>
    <p>处理后的姓名: 
        <%
            // 调用非标准方法,需要脚本片段
            String processedName = user.getName().toUpperCase();
            out.print(processedName);
        %>
    </p>
</body>
</html>

特点:

  • 优点
    • 比直接写脚本片段更规范,将 JavaBean 的操作与 HTML 分离。
    • 作用域管理更清晰。
  • 缺点
    • 主要用于操作简单的 JavaBean(数据对象)。
    • 如果要调用业务逻辑方法(如 UserService 中的方法),仍然需要结合脚本片段,无法完全避免。
    • 仍然在一定程度上将 Java 逻辑耦合在视图中。

在 Servlet 中调用 Java 方法,然后转发到 JSP(推荐做法)

这是现代 Java Web 开发的标准做法,遵循 MVC (Model-View-Controller) 设计模式。

  • Controller (控制器):通常是 HttpServlet,负责接收 HTTP 请求,调用业务逻辑,并将处理结果(数据)存入请求作用域。
  • Model (模型):JavaBean 或 Service/DAO 层,负责业务逻辑和数据处理。
  • View (视图):JSP,只负责展示从 Controller 传递过来的数据,不包含任何业务逻辑。

工作流程:

  1. 用户通过浏览器访问一个 URL,该 URL 映射到一个 Servlet
  2. Servlet(Controller)接收请求,调用 Service 层(Model)的方法来获取或处理数据。
  3. Servlet 将处理结果数据封装到 request 对象中。
  4. Servlet 使用 RequestDispatcher 将请求转发到一个 JSP 页面。
  5. JSP 页面(View)从 request 对象中取出数据,并使用 JSTL 或 EL 表达式进行展示。

示例:

模型层 - JavaBean 和 Service

User.java

public class User {
    private int id;
    private String name;
    // ... getter, setter, 构造函数 ...
}

UserService.java

public class UserService {
    public User findUserById(int id) {
        // 模拟从数据库查询
        User user = new User();
        if (id == 1) {
            user.setId(1);
            user.setName("张三");
        } else {
            user.setId(0);
            user.setName("未找到");
        }
        return user;
    }
}

控制器层 - Servlet

UserServlet.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("/user")
public class UserServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 获取请求参数
        String idStr = request.getParameter("id");
        int userId = Integer.parseInt(idStr);
        // 2. 调用Service层处理业务逻辑
        UserService userService = new UserService();
        User user = userService.findUserById(userId);
        // 3. 将数据存入request作用域
        request.setAttribute("user", user);
        // 4. 转发到JSP页面进行展示
        request.getRequestDispatcher("/user_display.jsp").forward(request, response);
    }
}

视图层 - JSP

为了在 JSP 中方便地访问 request 中的数据,我们通常会使用 JSTL (JSP Standard Tag Library)EL (Expression Language)

确保你的项目中包含了 JSTL 的 JAR 包(如 jstl-1.2.jar)。

user_display.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 引入JSTL核心标签库 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %
分享:
扫描分享到社交APP
上一篇
下一篇