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

以下是三种主要的方法,从最不推荐到最推荐的顺序排列。
在 JSP 中直接嵌入 Java 代码(不推荐)
这是最原始、最直接的方法,通过 JSP 的脚本元素(Scriptlets)将 Java 代码直接写在 JSP 页面中。
脚本片段
使用 <% ... %> 标签可以编写任意有效的 Java 代码片段。
示例:

假设我们有一个 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>
特点:

- 优点:简单直观,适合快速原型开发或小型脚本。
- 缺点:
- 严重违反 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 传递过来的数据,不包含任何业务逻辑。
工作流程:
- 用户通过浏览器访问一个 URL,该 URL 映射到一个
Servlet。 Servlet(Controller)接收请求,调用Service层(Model)的方法来获取或处理数据。Servlet将处理结果数据封装到request对象中。Servlet使用RequestDispatcher将请求转发到一个 JSP 页面。- 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" %
