第7章:JavaBean、Servlet 与 MVC——从 JSP 页面开发走向规范项目

一、前言

很多同学刚学 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. 优点

讲稿总结的优点有:

  1. JAVA 人员与美工开发人员分工明确

  2. JSP 中可以去掉大量 Java 代码

  3. JSP 负责前台显示,JavaBean 负责后台业务逻辑

  4. 开发速度较快

这几点都很好理解。


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

  • 跳转

  • 少量逻辑判断

这句话非常值得背。


二十、本章你必须背下来的结论

  1. JavaBean 本质上是普通 Java 类,用于封装数据和业务逻辑。

  2. JavaBean 的基本要求包括:放在包中、public class、属性封装、getter/setter、无参构造。

  3. JSP 通过 <jsp:useBean> 调用 JavaBean。

  4. <jsp:setProperty name="对象" property="*"/> 可以自动把表单参数映射到 Bean 属性。

  5. 自动映射成功的前提是:参数名与属性名一致。

  6. 使用 JavaBean 可以实现显示与业务分离:JSP 负责显示,JavaBean 负责业务。

  7. JSP + JavaBean 开发快,但耦合紧,不利于维护。

  8. Servlet 适合接收参数、调用 JavaBean、做跳转和简单逻辑判断。

  9. MVC 中:JSP 是 View,Servlet 是 Controller,JavaBean/DAO 是 Model。这个分工是从讲稿整体结构可直接归纳出来的。

  10. 更规范的 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 入门课最核心的知识骨架。


相关推荐
惊讶的猫2 小时前
springboot常用注解
java·spring boot·后端
tuyanfei2 小时前
SpringSecurity+jwt实现权限认证功能
java
yhole3 小时前
【SpringBoot】单元测试实战演示及心得分享
java
OKkankan3 小时前
撕 STL 系列:封装红黑树实现 mymap 和 myset
java·c++·算法
C蔡博士3 小时前
最近点对问题(Closest Pair of Points)
java·python·算法
APIshop3 小时前
Java调用亚马逊商品详情API接口完全指南
java·开发语言·python
不光头强3 小时前
jwt学习
java·大数据·学习
凸头3 小时前
美团Leaf发号器
java
SmartBrain3 小时前
基于 Spring AI 构建多智能体协作系统(高级版)
java·人工智能·spring