关于Servlet 与 MVC 设计模式

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

什么是mvc设计模式?

MVC 模式(Model-View-Controller)是软件工程中常见的一种软件架构模式,该模式把软件系统(项目)分为三个基本部分:模型(Model,简称 M)、视图(View,简称 V)和控制器(Controller,简称 C)。

使用 MVC 模式有很多优势

例如:简化后期对项目的修改、扩展等维护操作;使项目的某一部分变得可以重复利用;使项目的结构更加直观。

MVC 模式赋予了模型、视图和控制器三个组件各不相同的功能。

  1. 视图(View):负责界面的显示,以及与用户的交互功能,例如表单、网页等。
  2. 控制器(Controller):可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型。 实际开发中,通常用控制器对客户端的请求数据进行封装(如将 form 表单发来的若干个表单字段值,封装到一个实体对象中),然后调用某一个模型来处理此请求,最后再转发请求(或重定向)到视图(或另一个控制器)。
  3. 模型(Model):模型持有所有的数据、状态和程序逻辑。模型接收转发来的视图数据,并返回最终的处理结果。

实际开发中,通常用封装数据的 JavaBean 和封装业务的 JavaBean 两部分来实现模型层。

MVC 模式的流程:

浏览器通过视图向控制器发出请求,控制器接收到请求之后对数据进行封装,选择模型进行业务逻辑处理,随后控制器将模型处理结果转发到视图或下一个控制器,在视图层合并数据和界面模板生成 HTML 并做出最终响应,如图所示。

图片描述

在 MVC 模式中,视图 View 可以用 JSP/HTML/CSS 实现,模型 Model 可以用 JavaBean 实现,而控制器 Controller 就可以用 Servlet 来实现。

什么是servlet

Servlet 是基于 Java 技术的 Web 组件,运行在服务器端,由 Servlet 容器所管理,用于生成动态网页的内容。 Servlet 是一个符合特定规范的 Java 程序,编写一个 Servlet,实际上就是按照 Servlet 的规范编写一个 Java 类,Servlet 主要用于处理客户端请求并做出响应。

在绝大多数的网络应用中,客户端都是通过 HTTP 协议来访问服务器端资源。这就要求开发者编写的 Servlet 要适用于 HTTP 协议的请求和响应。这里讲解的 Servlet,实际就是讲解 HttpServlet 的相关类。

如果要开发一个能够处理 HTTP 协议的控制器 Servlet,就必须继承 javax.servlet.http. HttpServlet,并重写 doGet() 方法或 doPost() 方法,用来处理客户端发来的 get 请求或 post 请求,这两个方法简介如下表所示。

方 法 简 介
protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException 处理 get 方式的请求(如表单中的 method="get" 或超链接的请求方式)
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException 处理 post 方式的请求(如表单中的 method="post")

这里通过一个完整的例子来演示一个使用 MVC 的程序

1.建立mvn项目

名字:ServletMvc

image.png

image.png

在 pom.xml 文件中添加需要依赖的包。 com.shiyan在建立mvn项目时候自己设置的

<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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.shiyan</groupId>
  <artifactId>ServletMvc</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>ServletMvc Maven Webapp</name>
  <url>http://maven.apache.org</url>
    <dependencies>

       <!--引入外部依赖:mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
         <!--引入外部依赖:jsp-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <!--引入外部依赖:servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8080</port>
                    <uriEncoding>UTF-8</uriEncoding>
                    <path>/</path>
                    <finalName>ServletMvc </finalName>
                    <server>tomcat7</server>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
复制代码

在 \src\main\webapp 下添加注册界面 login.jsp,表单中有用户名、密码、年龄、地址四个字段。 这里的name值,是我们后面获取对应数据要使用的

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
    <form action="LoginServlet" method="post">
        用户名:<input type="text" name="uname" /><br/>
        密码:<input type="password" name="upwd" /><br/>
        年龄:<input type="text" name="uage" /><br/>
        地址:<input type="text" name="uaddress" /><br/>
        <input type="submit" value="登录" />
    </form>
</body>

</html>
复制代码

封装数据的 JavaBean ,在 \main\java\entity 下创建 User.java 类,User.java 中的字段和 login.jsp 中的字段一一对应。 实体类根据前面的jsp完成

image.png

封装业务的 JavaBean,在 \main\java\dao 下创建 UserDao.java 类。

image.png 在 \main\java\servlet 下添加控制器 LoginServlet.java 类,具体说明看代码中的注释。

image.png 在web.xml里面,添加 xml 映射关系。

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>org.lanqiao.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>

</web-app>
复制代码

在 \src\main\webapp 下添加欢迎页 welcome.jsp

<%@ page import="org.lanqiao.entity.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
欢迎您<%=((User)session.getAttribute("userInfo")).getUsername() %>
</body>
</html>
复制代码

打开数据库 在控制台依次执行下面代码。

show databases;                      #查看数据库
create database test;                #创建数据库
use test;                            #切换数据库
DROP TABLE IF EXISTS `userInfo`;
CREATE TABLE `userInfo` (
  `uname` varchar(255) DEFAULT NULL,
  `upwd` varchar(255) DEFAULT NULL,
  `uage` mediumint(255) DEFAULT NULL,
  `uaddress` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码

重启tomcat 登录后,回到数据库查看数据 查看数据表,如图所示。

图片描述

实验总结

  • 本程序实现一个注册功能,采用 Servlet2.5 实现,在本程序中,视图采用 JSP 来实现,模型采用 JavaBean 来实现,控制器采用 Servlet 来实现。

  • 执行的流程。

    图片描述

    程序中使用到的数据(用户信息),是通过模型中的 JavaBean(User.java)对象来传递的。

    • Servlet 生命周期包括加载、初始化、服务、销毁、卸载等 5 个部分,JSP 生命周期比 Servlet 生命周期多了一个“将 JSP 文件翻译成 Servlet ”的过程。
  • 在 Servlet 生命周期中,初始化 init() 方法只在第一次访问时执行一次;而 doGet() 或 doPost() 方法会在服务器每次接收请求时都执行一次;销毁 destroy() 方法只会在关闭服务时执行一次。

  • JSP 生命周期与 Servlet 生命周期相比只是多了一个将 JSP 文件翻译成 Servlet 的初始过程。

  • Servlet2.x 中 web.xml 的处理流程是:当用户发起请求后,Servlet 容器会在 web.xml 中 内的 里匹配指定的Servlet。如果匹配成功,就会根据 中的 值,再去匹配 中的 值。如果仍然匹配成功,就会去执行 中的 里面的 Servlet 实现类。最后再根据请求方式来决定执行 Servlet 实现类中的 doGet() 或 doPost() 方法。

  • Servlet3.0 和 Servlet2.5 的区别:Servlet3.0 不用在 web.xml 中配置 Servlet,而是直接使用 @WebServlet 在创建的 Servlet 类名前加上映射路径(相当于之前 web.xml 中的 ),如 @WebServlet("/WelcomeServlet30")

  • Servlet 提供了若干实用的 API。其中,ServletConfig 对象可以在 Servlet 初始化时,向该 Servlet 传递信息;ServletContext 表示 Web 应用的上下文,ServletContext 对象可以被 Servlet 容器中的所有 Servlet 共享;当客户端请求服务器端的 Servlet 时,Servlet 容器会创建一个 ServletRequest 对象和一个 ServletResponse 对象,分别封装请求信息和响应信息,

  • HttpServletRequest、HttpServletResponse 分别是 ServletRequest、ServletResponse 的两个常用子接口;Servlet 接口定义了 init()、service()、destroy() 等常见方法,还提供了 getServletConfig() 方法用于获取 ServletConfig 对象、getServletInfo() 方法用于获取 Servlet 信息等;GenericServlet 是一个抽象类,实现了 ServletConfig 接口、Servlet 接口和 Serializable 接口;HttpServlet 继承了 GenericServlet,对 GenericServlet 中的方法进行了实现。

猜你喜欢

转载自juejin.im/post/7101484317771038750
今日推荐