【Java Web编程 十四】深入理解MVC架构模式(一)

简介: 【Java Web编程 十四】深入理解MVC架构模式(一)

前面的十一篇博客把JSP和Servlet基本都详细的介绍了一遍,终于,我们的MVC架构模式横空出世,这也是框架诞生前的古早味Web程序的基本设计方式,事实上,即使框架诞生后,也不过是基于MVC模式的扩充和强化,所以理解MVC思想以及MVC早期的实现方式对于后续的框架学习以及理解Web开发的历史有很大的帮助。这篇Blog我将以一个简单的【用户注册登录】实践为主来串联之前十一篇Blog里提到的全部知识,在使用层面为Java Web编程系列划上一个句号。

MVC思想

MVC 全名是 Model View Controller,一种软件设计典范,用一种业务数据、逻辑、界面显示分离的方法组织代码,各部分职责如下:

  • 视图
    视图是用户看到并与之交互的界面。对老式的Web应用程序来说,视图就是由HTML元素组成的界面,在新式的Web应用程序中,HTML依旧在视图中扮演着重要的角色,但是已经被一些能显示动态数据的JSP逐步取代了,MVC好处是它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,不管这些数据来源是什么,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式
  • 模型
    模型表示企业数据和业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。不能将模型看出一个只有数据的类,其实模型也包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),现在一般会更加细分:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据业务两部分
  • 控制器
    控制器接受用户的输入并调用模型和视图去完成用户的需求,所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。

在前后端不分离的站点中,JSP充当了视图,Servlet充当了控制器,Model充当了模型。抽象意义上的职责如下图所示:

现在的MVC模型已经演化为如下操作过程,下面的整个项目就是依据这样的分层构建的

用户请求会先到达页面,填写信息后进入控制层流转,逻辑处理在Model层做,注意Model层也分两类:

  • Service:处理业务逻辑,这里的Model会返回给前端
  • Dao:处理持久化数据,这里的Model类似POJO,和数据库内的字段一一对应

当然对于我相对简单的一个系统,用一个贯穿的Model就可以了,但最后做解耦,因为落库的字段不一定和请求过来的字段完全一致。

项目构建

其实这个项目是5年前导师交给的一个任务,只完成了前端,当时用的是bootstrap实现的,后端完全没有,这次刚好学习完Java Web就把这部分补充上,项目名称为【黄金找矿网站】。

项目要求

在正式做之前先确定一下项目的要求,要求完成注册登录任务,任务需要满足如下几个要点:

  1. 未登录之前,除了注册登录页面,站点的其它页面均不能访问,请求时都自动跳转到登录页面
  2. 注册用户信息时,需要有前后端验证,对用户提交的表单进行表单验证
  3. 表单验证失败后收集错误信息跳转到错误页面,告知失败原因
  4. 注册成功后跳转到注册成功页面,告知用户的注册信息
  5. 登录时判断库里是否有该用户,只有存在且密码正确才可以登录成功
  6. 点击登出后当前用户恢复未登录状态
  7. 站点开启和关闭时需要加监控,监控服务的运行状态

其实这样一个注册登录项目就是我这两天设计出来用来将历史十一篇blog学习过的技术进行整合的,每个要求都涉及相关知识点。

技术要点

对照上边的实现要求,其实可以能抽象出所有的技术要点:

  1. 未登录之前,除了注册登录页面,站点的其它页面均不能访问,请求时都自动跳转到登录页面【Filter过滤器&重定向&Session作用域
  2. 注册用户信息时,需要有前后端验证,对用户提交的表单进行表单验证【表单提交&表单验证&请求转发&Servlet常用对象
  3. 表单验证失败后收集错误信息跳转到错误页面,告知失败原因【JSTL标签
  4. 注册成功后跳转到注册成功页面,告知用户的注册信息【JSP语法&EL表达式&JavaBean
  5. 登录时判断库里是否有该用户,只有存在且密码正确才可以登录成功【JDBC
  6. 点击登出后当前用户恢复未登录状态【Session销毁
  7. 站点开启和关闭时需要加监控,监控服务的运行状态【Listener监听器

好的,也就是说这个项目可以帮助我和大家复习整体的古早Java Web实现方式。

整体布局

整个项目的整体布局和分层如下:

项目所需的Maven配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>GoldenManage</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>GoldenManage</name>
    <packaging>war</packaging>
    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.7.1</junit.version>
    </properties>
    <dependencies>
        <!--引入servlet相关依赖,https://repo.maven.apache.org/maven2/javax/servlet/servlet-api/-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!--引入jsp相关依赖,https://repo.maven.apache.org/maven2/javax/servlet/jsp/jsp-api/-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
        </dependency>
        <!--引入junit测试引擎相关依赖-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/taglibs/standard -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
            </plugin>
        </plugins>
    </build>
</project>

代码清单

罗列下整体项目实现的代码清单吧,其中JSP中用到了前端框架BootStrap,这个就不展开讲了,前端框架一般是在没有前端同学帮助下使用的好利器。

JSP代码清单

JSP分为如下几个页面:login.jsp用于登录,register.jsp用于注册,logout.jsp用于登出,还有两个显示结果的页面:success.jsp和error.jsp,以及显示首页的index.jsp页面

login.jsp

<%--
  Created by IntelliJ IDEA.
  User: 13304
  Date: 2021/7/31
  Time: 16:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>用户登录</title>
    <link rel="shortcut icon" type="image/x-icon" href="images/cugbIcon.ico"/>
    <link rel="stylesheet" href="css/style.css" />
<body>
<div class="login-container">
    <h1>黄金矿工</h1>
    <div class="connect">
        <p>welcome to cugb</p>
    </div>
    <form action="ControlServlet" method="post" id="loginForm">
        <div>
            <input type="text" name="username" class="username" placeholder="用户名" autocomplete="off"/>
        </div>
        <div>
            <input type="password" name="password" class="password" placeholder="密码" oncontextmenu="return false" onpaste="return false" />
        </div>
        <button id="submit" type="submit">登 陆</button>
    </form>
    <a href="register.jsp">
        <button type="button" class="register-tis">注册</button>
    </a>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/common.js"></script>
<!--背景图片自动更换-->
<script src="js/supersized.3.2.7.min.js"></script>
<script src="js/supersized-init.js"></script>
<!--表单验证-->
<script src="js/jquery.validate.min.js?var1.14.0"></script>
</body>
</html>

logout.jsp

<%--
  Created by IntelliJ IDEA.
  User: 13304
  Date: 2021/7/31
  Time: 17:22
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>退出登录</title>
  <link rel="shortcut icon" type="image/x-icon" href="images/cugbIcon.ico"/>
  <link rel="stylesheet" href="css/style.css" />
<body>
<div class="login-container">
  <h1>黄金矿工</h1>
  <div class="connect">
    <p>welcome to cugb</p>
  </div>
  <form action="StopServlet" method="get" id="loginForm">
    <button id="submit" type="submit">确认登出</button>
  </form>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/common.js"></script>
<!--背景图片自动更换-->
<script src="js/supersized.3.2.7.min.js"></script>
<script src="js/supersized-init.js"></script>
<!--表单验证-->
<script src="js/jquery.validate.min.js?var1.14.0"></script>
</body>
</html>

register.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>用户注册</title>
    <link rel="stylesheet" href="css/style.css" />
    <link rel="shortcut icon" type="image/x-icon" href="images/cugbIcon.ico"/>
<body>
<div class="register-container">
    <h1>黄金矿工</h1>
    <div class="connect">
        <p>welcome to cugb</p>
    </div>
    <%--onpaste是否运行粘贴;oncontextmenu 是否允许展开右键菜单;placeholder 输入提示;autocomplete是否允许浏览器自动补齐--%>
    <form action="GetPermission" method="post" id="registerForm">
        <div>
            <input type="text" name="name"  placeholder="您的用户名" autocomplete="off" />
        </div>
        <div>
            <input type="password" name="password" class="password" placeholder="输入密码" oncontextmenu="return false" onpaste="return false" />
        </div>
        <div>
            <input type="password" name="confirm_password" class="confirm_password" placeholder="再次输入密码" oncontextmenu="return false" onpaste="return false" />
        </div>
        <div>
            <input type="text" name="phone_number" class="phone_number" placeholder="输入手机号码" autocomplete="off" id="number"/>
        </div>
        <div>
            <input type="email" name="email" class="email" placeholder="输入邮箱地址" oncontextmenu="return false" onpaste="return false" />
        </div>
        <button id="submit" type="submit" style="width: 332px">注 册</button>
    </form>
    <a href="login.jsp">
        <button type="button" class="register-tis" style="width: 332px">返回登录</button>
    </a>
</div>
<script src="js/jquery.min.js"></script>
<!--背景图片自动更换-->
<script src="js/supersized.3.2.7.min.js"></script>
<script src="js/supersized-init.js"></script>
<!--表单验证-->
<script src="js/jquery.validate.min.js?var1.14.0"></script>
<script src="js/common.js"></script>
</body>
</html>
相关文章
|
8天前
|
网络协议 Java Shell
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
40 7
|
13天前
|
人工智能 JavaScript 安全
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
57 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
1月前
|
Kubernetes Java 持续交付
小团队 CI/CD 实践:无需运维,Java Web应用的自动化部署
本文介绍如何使用GitHub Actions和阿里云Kubernetes(ACK)实现Java Web应用的自动化部署。通过CI/CD流程,开发人员无需手动处理复杂的运维任务,从而提高效率并减少错误。文中详细讲解了Docker与Kubernetes的概念,并演示了从创建Kubernetes集群、配置容器镜像服务到设置GitHub仓库Secrets及编写GitHub Actions工作流的具体步骤。最终实现了代码提交后自动构建、推送镜像并部署到Kubernetes集群的功能。整个过程不仅简化了部署流程,还确保了应用在不同环境中的稳定运行。
75 9
|
2月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
103 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
3月前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
87 7
|
3月前
|
Java 持续交付 项目管理
使用Maven进行项目管理:提高Java Web开发的效率
Maven 是一款强大的项目管理和构建自动化工具,广泛应用于Java社区。它通过依赖管理、构建生命周期管理、插件机制和多模块项目支持等功能,简化了项目的构建过程,提高了开发效率。本文将介绍Maven的核心功能及其在Java Web开发中的应用。
90 0
|
3月前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
110 4
|
3月前
|
存储 前端开发 调度
Flux 与传统的 MVC 架构模式区别
Flux是一种用于构建用户界面的架构模式,与传统的MVC架构不同,它采用单向数据流,通过Dispatcher统一管理数据的分发,Store负责存储数据和业务逻辑,View只负责展示数据,使得应用状态更加可预测和易于维护。
WK
|
3月前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
168 0
|
4月前
|
前端开发 Java API
JAVA Web 服务及底层框架原理
【10月更文挑战第1天】Java Web 服务是基于 Java 编程语言用于开发分布式网络应用程序的一种技术。它通常运行在 Web 服务器上,并通过 HTTP 协议与客户端进行通信。
67 1