【JavaWeb学习 | 第18篇】Servlet与MVC开发模式

在上一篇文章中,我们详细学习了 JSP九大内置对象,掌握了JSP如何动态生成页面。
但如果把所有业务逻辑、数据处理、页面展示全部写在JSP里(早期Model1模式),代码会非常混乱、难以维护。

MVC模式的出现,就是为了解决这个问题。它将“数据、业务逻辑、界面展示”彻底分离,让开发更清晰、更易扩展


一、什么是MVC模式?

MVCModel-View-Controller 的缩写,是一种经典的软件设计模式,特别适合Web开发。

组件 英文全称 对应JavaWeb技术 主要职责
Model(模型) Model JavaBean(实体类 + 业务类) 封装数据 + 处理业务逻辑(增删改查、计算等)
View(视图) View JSP(或HTML + EL + JSTL) 负责数据展示,只做“看”的工作,不处理复杂逻辑
Controller(控制器) Controller Servlet 接收用户请求、调用Model处理业务、选择合适的View返回给用户

工作流程(核心理解点)

  1. 用户在浏览器发出请求(例如点击登录按钮) → 请求到达 Controller(Servlet)
  2. Servlet(Controller)接收请求参数,调用 Model(JavaBean/Service/DAO)进行业务处理
  3. Model处理完后返回数据给 Controller
  4. Controller把数据存入作用域(request/session),然后转发或重定向到对应的 View(JSP页面)
  5. JSP(View)使用EL表达式或JSTL从作用域中取出数据并展示给用户

优点

  • 分层清晰,职责单一
  • 便于团队协作(前端写JSP,后端写Servlet+JavaBean)
  • 代码可维护性、可扩展性大大提高
  • 后期容易过渡到Spring MVC等框架

二、JavaWeb经典开发模式演进

  1. Model1(早期):JSP + JavaBean
    JSP既当Controller又当View,适合小型项目,逻辑复杂后难以维护。

  2. Model2(推荐)Servlet + JSP + JavaBean(即MVC模式)
    Servlet做控制器,JSP做视图,JavaBean做模型。这是我们本篇重点学习的模式。

  3. 三层架构(实际开发常用)
    在MVC基础上进一步细化Model层:

    • 表示层(Web层):Servlet + JSP(Controller + View)
    • 业务逻辑层(Service层):处理复杂业务(如登录时检查权限、发邮件等)
    • 数据访问层(DAO层):专门与数据库交互(CRUD操作)

    实体类(POJO/JavaBean)通常放在Model中,被Service和DAO共用。


三、MVC模式核心代码示例(用户登录)

1. Model层 —— User实体类
// com.example.model.User.java
public class User {
    private String username;
    private String password;
    // getter & setter + 无参构造
    public User() {}
    // ... 省略getter/setter
}
2. Controller层 —— LoginServlet
// com.example.web.LoginServlet.java
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        // 1. 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        
        // 2. 调用Model处理业务
        UserService service = new UserService();  // 实际项目中常用Service层
        User user = service.login(username, password);
        
        // 3. 根据结果选择View
        if (user != null) {
            // 登录成功,数据放入session
            req.getSession().setAttribute("user", user);
            // 转发到成功页面(地址栏不变)
            req.getRequestDispatcher("/success.jsp").forward(req, resp);
        } else {
            // 登录失败,放入错误信息到request
            req.setAttribute("errorMsg", "用户名或密码错误!");
            // 转发回登录页面
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}
3. View层 —— login.jsp(登录页面)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>用户登录</title></head>
<body>
    <h2>用户登录</h2>
    
    <%-- 显示错误信息 --%>
    <span style="color:red;">${errorMsg}</span>
    
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>
4. View层 —— success.jsp(成功页面)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>登录成功</title></head>
<body>
    <h2>欢迎您,${user.username}!</h2>
    <a href="${pageContext.request.contextPath}/logout">退出登录</a>
</body>
</html>

四、MVC开发中的关键技术点

  • 请求转发(forward):request.getRequestDispatcher().forward()
    服务器内部跳转,地址栏不变,request作用域数据共享。
  • 重定向(redirect):response.sendRedirect()
    客户端跳转,地址栏改变,request作用域数据丢失。
  • ${pageContext.request.contextPath}:动态获取项目路径,避免硬编码。
  • EL表达式 + JSTL:在JSP中尽量少写Java脚本,让页面更干净。
  • 过滤器(Filter)监听器(Listener):常配合MVC使用(如统一编码、登录权限检查)。

五、实际开发建议与注意事项

  1. 包结构推荐(三层架构):

    • com.example.model → 实体类(User、Product等)
    • com.example.dao → 数据访问层(UserDao)
    • com.example.service → 业务逻辑层(UserService)
    • com.example.web → Servlet控制器
    • com.example.utils → 工具类
    • webapp/ → JSP页面、静态资源(css、js、images)
  2. 不要在JSP中写复杂Java代码,尽量只做展示。

  3. Servlet中不要写数据库连接代码,应该交给DAO层。

  4. 使用JavaBean封装数据,便于在不同层之间传递。

  5. 早期学习时可以先用纯Servlet+JSP+JavaBean,掌握后再学习Spring MVC框架(它对MVC做了更优雅的实现)。


六、练习建议(强烈推荐动手做)

  1. 基于本篇示例,完整实现用户登录 + 注册功能。
  2. 增加记住我(Cookie)功能。
  3. 实现一个简单的商品列表展示(Servlet查询数据 → 存入request → JSP用JSTL循环展示)。
  4. 尝试把登录逻辑拆分成 UserDao + UserService + LoginServlet 三层。

做完这些,你会深刻体会到“分层”带来的清晰感和成就感!


系列文章导航(持续更新中)

  • 第16篇:JSP基础语法
  • 第17篇:JSP内置对象
  • 第18篇:Servlet与MVC(本文)
  • 第19篇:预计将介绍 Filter过滤器 + Listener监听器(权限控制、编码过滤等)

有任何问题(如想看注册功能的完整代码、或三层架构的更多细节),欢迎在评论区留言!

继续加油!从Model1到MVC,是JavaWeb开发思维的一次重要升级,你已经走在正确的道路上!💪

下一篇文章见~ 🚀

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐