一、前言
很多同学刚学 JSP 时,写代码都是这种风格:
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
if("admin".equals(username) && "123".equals(password)){
%>
<h2>登录成功</h2>
<%
}else{
%>
<h2>登录失败</h2>
<%
}
%>
刚开始这样写没问题。
因为:
-
页面少
-
功能简单
-
逻辑不复杂
但一旦项目稍微大一点,就会立刻出问题:
-
JSP 里全是 Java 代码
-
HTML 和业务逻辑混在一起
-
一个页面又接收参数、又判断、又查数据、又输出结果
-
后期改功能特别痛苦
所以 Web 项目开发到后面,一定会走向分工:
页面显示交给谁?
JSP
业务逻辑交给谁?
JavaBean
请求控制和跳转交给谁?
Servlet
这就是本章要讲清楚的核心。
二、为什么不建议把所有代码都写在 JSP 里
讲稿里其实已经给了很明确的方向:
使用 JavaBean 可以达到显示与业务的分离。显示:JSP;业务:JavaBean。
JAVA 开发人员专注于具体业务的开发,而 JSP 开发人员专注于显示效果的开发。
这两句话非常重要。
1. JSP 最擅长什么
JSP 的优点,讲稿总结得很直接:
JSP 优点:开发前台界面方便,做 UI 开发容易。
也就是说,JSP 最适合干的是:
-
写页面结构
-
显示数据
-
做简单输出
-
控制页面效果
它不适合承担太多复杂业务处理。
2. 为什么 JSP 不适合堆太多业务逻辑
因为一旦业务逻辑复杂,你会遇到这些问题:
-
页面特别乱
-
重复代码很多
-
不利于复用
-
美工/前端和 Java 开发没法分工
-
后期修改一处,影响很多页面
所以更规范的方式就是:
让 JSP 负责"看起来怎么样"
让 JavaBean/Servlet 负责"到底怎么处理"
三、JavaBean 到底是什么
讲稿里给的定义非常直接:
JavaBean 就是一个 Java 类,只是没有图形显示代码,主要完成基本业务逻辑。
JavaBean 可以使用 Java 的封装、继承、多态。
使用 JavaBean 封装许多可重复调用的代码。
所以你可以先把 JavaBean 理解成:
专门拿来封装数据和业务逻辑的普通 Java 类
1. JavaBean 最核心的作用
作用一:封装数据
比如用户信息、学生信息、图书信息。
作用二:封装业务逻辑
比如:
-
登录验证
-
数据处理
-
结果计算
-
数据库操作的中间逻辑
作用三:提高复用性
同一段业务逻辑,不必在多个 JSP 页面里重复写。
2. 为什么 JavaBean 很重要
讲稿里甚至说得比较重:
不会 JavaBean 的开发人员,不能称为 J2EE 开发人员。
这句话当然带点课堂强调意味,但核心意思没错:
JavaBean 是 JSP/Java Web 开发里最基础的业务封装手段之一。
四、JavaBean 的编写要求
这部分讲稿列得非常清楚,几乎就是考试点。
1. 必须放在一个包中
例如:
package jlnu.zjh;
2. 必须是 public class
例如:
public class SimpleBean {
}
3. 属性必须封装
也就是:
-
属性一般写成
private -
不能随便直接暴露
例如:
private String name;
private int age;
4. 通过 setter / getter 设置和获取属性
例如:
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
5. 如果要通过 JSP 标签调用,必须有无参构造方法
讲稿明确强调:
使用 JSP 标签去调用 JavaBean 时,必须有一个无参构造方法。
五、一个最基础的 JavaBean 例子
下面先写一个最标准、最适合入门的 JavaBean。
SimpleBean.java
package jlnu.zjh;
public class SimpleBean {
private String name;
private String password;
private int age;
public SimpleBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
这个类就符合 JavaBean 的基本规范:
-
在包里
-
public class -
属性私有
-
有 getter / setter
-
有无参构造
六、JavaBean 文件放在哪里
讲稿里明确说:
将 JavaBean 编译好的
.class文件拷贝到WEB-INF/classes文件夹之下;如果没有,则可以自己建立。
WEB-INF/classes本质上是一个 classpath 路径。
所以在传统 JSP/Tomcat 课程环境下,你可以这样理解:
源文件
写成 .java
编译后
得到 .class
放置位置
放到:
WEB-INF/classes/包名路径/
例如:
WEB-INF/classes/jlnu/zjh/SimpleBean.class
七、JSP 中如何调用 JavaBean
讲稿里给出的标准标签是:
<jsp:useBean id="sb" scope="page" class="jlnu.zjh.SimpleBean"/>
这行代码特别重要。
1. id
表示实例化对象的名字
例如:
id="sb"
后面你就用 sb 代表这个 Bean 对象。
2. scope
表示作用范围
例如:
scope="page"
也可以是:
-
page -
request -
session -
application
这和前一章四大作用域是对应的。
3. class
表示 JavaBean 的完整类名
例如:
class="jlnu.zjh.SimpleBean"
也就是:
包名 + 类名
4. 最完整的调用示例
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<jsp:useBean id="sb" scope="page" class="jlnu.zjh.SimpleBean"/>
<%
sb.setName("张三");
sb.setPassword("123456");
sb.setAge(20);
%>
<h2>姓名:<%= sb.getName() %></h2>
<h2>密码:<%= sb.getPassword() %></h2>
<h2>年龄:<%= sb.getAge() %></h2>
这就是最基础的"JSP 调 JavaBean"。
八、<jsp:setProperty> 和 <jsp:getProperty> 到底怎么用
这一块是讲稿里的重点。
讲稿明确说:
使用 JavaBean 可以替代掉一切 setter 方法调用。
<jsp:setProperty name="sb" property="*"/>可以自动匹配。参数名与 Bean 属性名一致时,可以通过反射自动找到对应的
setXxx()方法。
1. 先看手动 setter 的写法
<jsp:useBean id="sb" scope="page" class="jlnu.zjh.SimpleBean"/>
<%
sb.setName(request.getParameter("name"));
sb.setPassword(request.getParameter("password"));
sb.setAge(Integer.parseInt(request.getParameter("age")));
%>
这当然能用,但写起来比较繁琐。
2. 用 setProperty 自动设置
<jsp:useBean id="sb" scope="page" class="jlnu.zjh.SimpleBean"/>
<jsp:setProperty name="sb" property="*"/>
这句的意思是:
自动把表单参数填充到 Bean 中同名属性里
前提是:
-
表单的
name -
JavaBean 的属性名
-
setter 方法名
三者要匹配。
3. 为什么它能自动匹配
讲稿里给出的解释是:
根本原因是使用 Java 的反射机制,根据参数名称找到相应的方法。
比如参数名为
name,就会自动找到setName()。
你现在不用深究反射细节,只要记住这个结论:
表单参数名和 Bean 属性名一致时,
property="*"特别好用。
4. setProperty 的几种写法
讲稿列了几种:
自动匹配
<jsp:setProperty name="sb" property="*"/>
设置指定属性
<jsp:setProperty name="sb" property="name"/>
指定参数来源
<jsp:setProperty name="sb" property="name" param="password"/>
直接指定固定值
<jsp:setProperty name="sb" property="name" value="hello"/>
5. getProperty 的用法
虽然讲稿重点更偏向 setProperty,但 JSP 中通常也会配套用:
<jsp:getProperty name="sb" property="name"/>
例如:
<jsp:useBean id="sb" scope="page" class="jlnu.zjh.SimpleBean"/>
<jsp:setProperty name="sb" property="*"/>
<h2>姓名:<jsp:getProperty name="sb" property="name"/></h2>
<h2>年龄:<jsp:getProperty name="sb" property="age"/></h2>
九、JavaBean 的智能之处:自动类型转换
讲稿里专门强调了这一点:
使用 JavaBean 的
setProperty方法,可以自动将传递过来的只有数字的字符串变为整型,再赋值给具体属性。
这非常适合初学者理解。
1. 比如表单传过来的是
age = "20"
这是字符串。
2. 但如果你的 Bean 里写的是
private int age;
public void setAge(int age){ ... }
那么使用:
<jsp:setProperty name="sb" property="*"/>
时,JSP 容器会尝试自动把 "20" 转成 int 20。
所以这一点比你手动写 request.getParameter() 更省事。
十、JSP + JavaBean:模式1 的优点和缺点
讲稿里对这种模式讲得非常清楚。
1. 优点
讲稿总结的优点有:
-
JAVA 人员与美工开发人员分工明确
-
JSP 中可以去掉大量 Java 代码
-
JSP 负责前台显示,JavaBean 负责后台业务逻辑
-
开发速度较快
这几点都很好理解。
2. 缺点
讲稿也直接指出:
JSP 与 JavaBean 紧密耦合在一起,程序开发完成之后不利于维护。
这就是问题所在。
例如:
-
JSP 直接 new / 调 Bean
-
页面里知道太多业务细节
-
改 Bean 可能影响很多 JSP
-
美工和 Java 逻辑仍然容易互相牵制
讲稿还特别举了很真实的团队协作矛盾:
美工说你先开发好 Java 程序我再做页面;
开发说你先做好页面我再写逻辑。
这本质上就是耦合过紧。
十一、为什么需要 Servlet
这时 Servlet 就登场了。
讲稿对 Servlet 的定位非常明确:
Servlet 优点:是 Java 程序,安全性高,性能也高;
Servlet 也可以像 JSP 一样接收用户请求参数;
但 Servlet 的缺点是显示不方便。
所以你可以把 Servlet 理解成:
专门负责"中间调度"的控制器
1. Servlet 最擅长什么
-
接收请求参数
-
做逻辑判断
-
调用 JavaBean
-
跳转到 JSP 页面
这和讲稿总结的最佳实践完全一致:
Servlet 中最好只有以下几种代码:
接收参数、调用 JavaBean、进行跳转、做一些简单逻辑判断。
这句话非常值得背。
2. Servlet 不适合什么
Servlet 不适合写复杂页面显示。
因为它本质上是 Java 类,不像 JSP 那样天然适合写 HTML 界面。
所以最合理的分工就是:
-
Servlet 负责控制
-
JavaBean 负责业务
-
JSP 负责显示
十二、MVC 到底是什么
这就是本章的最终目标。
讲稿里给出的链路非常清楚:
JSP → Servlet → JavaBean
JSP 跳转到 Servlet 可以,通过表单提交或超链接;
Servlet 跳转到 JSP 可以。
这其实就是 MVC 思想在课程里的落地版。
1. MVC 三层分工
M = Model(模型)
这里主要对应:
-
JavaBean
-
DAO
-
业务逻辑
-
数据处理
V = View(视图)
这里主要对应:
-
JSP 页面
-
页面显示
-
用户界面
C = Controller(控制器)
这里主要对应:
-
Servlet
-
接收请求
-
调用 Model
-
决定跳转到哪个 JSP
2. 为什么 MVC 更好
讲稿明确说:
使用 MVC 开发程序,代码稍微复杂;
但 Servlet 根据 JavaBean 返回内容进行跳转;
JSP 与 JavaBean 之间没有特别明显的直接关系。
这说明:
-
MVC 初学时会觉得麻烦
-
但它把耦合拆开了
-
后期更容易维护和扩展
十三、一个最基础的 MVC 流程图思维
你可以把登录功能想成这样:
第一步:JSP 显示登录表单
用户在页面中输入用户名和密码。
第二步:表单提交到 Servlet
Servlet 接收参数:
req.getParameter("username")
req.getParameter("password")
第三步:Servlet 调用 JavaBean
JavaBean 去做验证逻辑。
第四步:Servlet 根据结果跳转
-
成功 → success.jsp
-
失败 → fail.jsp
这就是最经典的 MVC 基础流程。
十四、Servlet 跳转到 JSP 怎么写
讲稿里给了非常标准的代码:
req.getRequestDispatcher("mvcdemo.jsp").forward(req,resp);
并明确指出:
Servlet 跳转到 JSP 的服务器端跳转指令就是这个。
1. 示例 Servlet
package zjh.servlet;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MVCServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
this.doPost(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
req.setAttribute("name", "zhaojh");
req.getRequestDispatcher("mvcdemo.jsp").forward(req, resp);
}
}
这段代码和讲稿中的 MVCServlet 示例是一致的。
2. JSP 页面接收显示
mvcdemo.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<h2>姓名:<%= request.getAttribute("name") %></h2>
这就形成了:
-
Servlet 负责放值
-
JSP 负责显示值
十五、一个完整的 MVC 登录小案例
下面我给你写一个最适合课程理解的精简版。
1. JSP:登录页 login.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<form action="login.do" method="post">
用户名:<input type="text" name="username"><br><br>
密码:<input type="password" name="password"><br><br>
<input type="submit" value="登录">
</form>
</body>
</html>
2. JavaBean:UserBean.java
package jlnu.zjh;
public class UserBean {
private String username;
private String password;
public UserBean() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean checkLogin() {
return "admin".equals(username) && "123456".equals(password);
}
}
3. Servlet:LoginServlet.java
package jlnu.zjh;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
this.doPost(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
UserBean user = new UserBean();
user.setUsername(username);
user.setPassword(password);
if(user.checkLogin()) {
req.setAttribute("username", username);
req.getRequestDispatcher("success.jsp").forward(req, resp);
} else {
req.getRequestDispatcher("fail.jsp").forward(req, resp);
}
}
}
4. 成功页 success.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<h2>登录成功,欢迎你:<%= request.getAttribute("username") %></h2>
5. 失败页 fail.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<h2>登录失败,用户名或密码错误!</h2>
十六、这个 MVC 案例到底体现了什么
你一定要能说清楚这 3 层各自干了什么。
JSP 做了什么
-
提供登录表单
-
显示成功/失败页面
Servlet 做了什么
-
接收参数
-
创建 Bean
-
调用 Bean 的业务方法
-
决定跳转哪一个 JSP
JavaBean 做了什么
-
封装用户数据
-
提供登录验证逻辑
这就是最标准的课程级 MVC 分工。
十七、DAO 是什么,为什么讲稿里提到了
讲稿后面顺带提到:
查询过程可以封装成 DAO 接口、DAO 实现类、工厂类。
这说明课程最后其实已经在往更规范的项目结构靠了。
1. DAO 的作用
DAO = Data Access Object
简单理解:
专门负责和数据库打交道
比如:
-
查询用户
-
插入学生信息
-
删除图书
-
修改成绩
如果把数据库代码全写在 JSP 或 Servlet 里,也会很乱。
所以更规范的方式是:
-
JSP:显示
-
Servlet:控制
-
JavaBean:业务对象
-
DAO:数据库访问
2. 你现在阶段怎么理解就够了
你现在不用把 DAO 学太深,先记住:
JavaBean 不一定只保存属性,也可以逐渐承担业务逻辑;而真正数据库访问再往下可以拆到 DAO。
这就是项目越来越规范的方向。
十八、JSP + JavaBean 和 MVC 到底怎么选
讲稿给出了很明确的结论。
1. JSP + JavaBean(模式1)
优点
-
写得快
-
适合小项目
-
适合一次性作业
-
人少时方便
缺点
-
JSP 和 JavaBean 耦合紧
-
后期维护麻烦
-
页面和业务边界还不够清晰
讲稿直接说:
适合于一次开发完成,而且团队成员较少时使用。
2. JSP + Servlet + JavaBean(MVC)
优点
-
分工明确
-
JSP 更干净
-
逻辑更清晰
-
更利于维护和扩展
缺点
-
代码结构更复杂
-
初学时会觉得麻烦
所以课程学习层面可以这样记:
小作业:JSP + JavaBean 就够用
稍微规范一点的项目:上 MVC
十九、本章最容易混淆的 8 个点
1. JavaBean 不是"特殊语法"
它本质上就是符合规范的 Java 类。
2. JSP 可以调用 JavaBean,但这不代表 JSP 应该写满业务逻辑
JSP 主要还是负责显示。
3. Servlet 不是拿来写漂亮页面的
Servlet 适合控制,不适合直接写复杂 HTML。
4. <jsp:setProperty property="*"> 不是魔法
它只是根据参数名和属性名自动匹配 setter。
5. 表单参数名和 Bean 属性名不一致时,自动匹配会失败
这是 property="*" 最容易踩的坑。
6. JavaBean 被 JSP 标签调用时需要无参构造
这是硬要求。
7. MVC 更规范,但代码会比纯 JSP 复杂
讲稿明确提到这一点。
8. Servlet 最好只保留四类代码
-
接收参数
-
调用 JavaBean
-
跳转
-
少量逻辑判断
这句话非常值得背。
二十、本章你必须背下来的结论
-
JavaBean 本质上是普通 Java 类,用于封装数据和业务逻辑。
-
JavaBean 的基本要求包括:放在包中、
public class、属性封装、getter/setter、无参构造。 -
JSP 通过
<jsp:useBean>调用 JavaBean。 -
<jsp:setProperty name="对象" property="*"/>可以自动把表单参数映射到 Bean 属性。 -
自动映射成功的前提是:参数名与属性名一致。
-
使用 JavaBean 可以实现显示与业务分离:JSP 负责显示,JavaBean 负责业务。
-
JSP + JavaBean 开发快,但耦合紧,不利于维护。
-
Servlet 适合接收参数、调用 JavaBean、做跳转和简单逻辑判断。
-
MVC 中:JSP 是 View,Servlet 是 Controller,JavaBean/DAO 是 Model。这个分工是从讲稿整体结构可直接归纳出来的。
-
更规范的 Web 项目开发,应尽量让 JSP、Servlet、JavaBean 各司其职。
二十一、本章练习题
练习1
自己写一个 StudentBean,包含:
-
name -
age -
score
并写出 getter / setter。
练习2
写一个 JSP 页面,用 <jsp:useBean> 调用 StudentBean,并手动给属性赋值后显示出来。
练习3
写一个表单页面,输入姓名和年龄;提交到结果页,用 <jsp:setProperty property="*"/> 自动给 Bean 赋值并显示。
练习4
写一个最简单的登录 MVC 案例:
-
login.jsp -
LoginServlet -
UserBean -
success.jsp -
fail.jsp
练习5
思考并回答:
为什么 JSP + JavaBean 适合小作业,而 MVC 更适合规范项目?
二十二、本章小结
这一章你学到的,其实不是几个标签和类,而是一种更成熟的开发思想。
你现在应该已经明白:
-
JSP 不该什么都干
-
JavaBean 的意义不只是"存数据",更重要的是封装和复用
-
Servlet 的价值在于控制流程和解耦
-
MVC 的本质不是"多写几个文件",而是让显示、控制、业务三部分各自独立
到这里,这套《网络程序设计》7章主线其实就完整了。
你已经从:
-
浏览器 / 服务器 / Tomcat
-
HTML / 表单 / 表格
-
JSP 语法
-
request / response
-
Cookie / Session
一路走到了:
-
JavaBean
-
Servlet
-
MVC
这基本就是一门 Web 入门课最核心的知识骨架。