Servlet 入门到精通(四)

上一篇博客的传送门:Servlet 入门到精通(三)

MVC模式

前几天的学习过程中,我们可以通过JSP页面直接产生service层的对象,调用相应的方法。但是这样书写后,带来的影响是前端程序员也需要有良好的Java代码功底,而这种情况不太现实,这时候我们需要将页面中的Java代码分离出去,交由专门的模块去负责,页面只需要做内容展示和收集即可。这里我们就引入了MVC设计模式。

MVC模式中,Model是指业务模型,View是指用户界面,Controller则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。分工合作完成整体项目的推进,用于把前端页面的展现与后端业务分离。

  • Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。
  • View(视图) - 呈现给用户的部分,是用户和程序交互的接口。
  • Controller(控制器) - 用来进行用户的交互,接收用户的请求,对请求做出响应。控制器中接收了用户与界面交互时传递过来的数据,并根据数据业务逻辑来执行服务的调用和更新业务模型的数据和状态。目的是使得模型和实体分离。

Servlet概述

Servlet(Server Applet)是 Java Servlet 的简称,称为小服务程序或服务连接器,用Java 编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态 Web 内容。

狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类,一般情况下,人们将 Servlet 理解为后者。Servlet 运行于支持 Java的应用服务器中。

从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下Servlet 只用来扩展基于 HTTP 协议的 Web 服务器。最早支持 Servlet 标准的是 JavaSoft 的 Java Web Server,此后,一些其它的基于Java 的 Web 服务器开始支持标准的 Servlet。

Web容器、Http服务器和Servlet容器

HTTP 服务器负责接收用户请求和对用户的请求做出响应,主要的作用是解析。

Servlet 容器负责加载Servlet Class,并实现对它的管理。

Web 容器其实就是 HTTP 服务器 + Servlet 容器,因为单单 Servlet 容器没有解析 HTTP 请求、通信等相关功能。所以把 Tomcat、Jetty 等实现包含了 HTTP 服务器和 Servlet 容器的功能,称之为 Web 容器。

Servlet实现方式

maven的pom.xml中引入依赖

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

如果使用的是 tomcat10 的服务器,引入以下依赖:

<dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>5.0.0</version>
</dependency>
<dependency>
      <groupId>jakarta.servlet.jsp</groupId>
      <artifactId>jakarta.servlet.jsp-api</artifactId>
      <version>3.0.0</version>
</dependency>
<dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>jakarta.servlet.jsp.jstl</artifactId>
      <version>3.0.1</version>
</dependency>

实现一个接口 Servlet,重写五个方法

// 第一种实现方式
/*
    1.实现Servlet接口
    2.重写这个接口的五个方法
    3.给当前类设置URL路径
 */
public class FirstServlet implements Servlet {
    private ServletConfig config;

    // 初始化方法 会在Servlet创建时调用,并且只会调用一次
    // 默认情况下,在第一次请求时创建当前Servlet
    public void init(ServletConfig config) throws ServletException {
        this.config = config; // 将局部变量的值赋予给成员变量
        System.out.println("我是FirstServlet的初始化方法!");
    }

    // 获取到config对象
    public ServletConfig getServletConfig() {
        return config;
    }

    // 服务方法 最重要的方法 每一次请求访问这个方法
    public void service(ServletRequest req, ServletResponse resp)
            throws ServletException, IOException {
        System.out.println("我是FirstServlet的service方法!");
        resp.getWriter().println("Hello,World!"); // 输入内容到页面
    }

    // 返回当前Servlet的信息
    public String getServletInfo() {
        return "我是FirstServlet";
    }

    // 销毁方法,会在Servlet被销毁时执行,并且只执行一次 服务器关闭时
    public void destroy() {
        System.out.println("FirstServlet被销毁了!");
    }
}

继承一个抽象类 GenericServlet,重写 service 方法

// 第二种实现方式
/*
    1.继承GenericServlet抽象类
    2.重写service方法
    3.在web.xml中注册当前Servlet或者注解注册
 */
public class SecondServlet extends GenericServlet {
    @Override
    public void service(ServletRequest req, ServletResponse resp)
            throws ServletException, IOException {
        System.out.println("我是SecondServlet的服务方法!");
    }
}

继承一个类 HttpServlet,重写指定方法,只针对于 HTTP 协议。

// 第三种实现方式 最常用的实现方式
/*
    1.继承HttpServlet,只针对于Http协议
    2.重写doGet和doPost请求
    3.使用注解或者XML的方式来注册Servlet(注解和xml方式可以互换)
 */
public class ThirdServlet extends HttpServlet {

    // 处理所有的get请求
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("我是ThirdServlet的get请求");
    }
    // 处理所有的post请求
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("我是ThirdServlet的post请求");
    }

}

注册我们写好的Servlet

web.xml方式

<!--设置Servlet的URL路径-->
<servlet>
   <servlet-name>first</servlet-name>
   <servlet-class>pack0410.servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>first</servlet-name>
   <!--/代表根目录  webapp文件就是根目录-->
   <url-pattern>/a</url-pattern>
</servlet-mapping>

注解方式 

@WebServlet("/c")
public class ThirdServlet extends HttpServlet {
    // 其他代码忽略
}

Servlet体系结构

service()、doGet()和doPost()之间的区别?

答:首先service()是服务方法,是Servlet接口定义的服务规范,doGet()和doPost()是HttpServlet类特有的方法;其次,service()方法可以接收所有类型的请求,而doGet()方法只能接收get类型的请求,doPost()方法只能接收post类型的请求,相似的方法还有doPut()、doDelete()等;最后doGet()和doPost()方法是针对于HTTP协议才有效果的。 

Servlet加载流程

Servlet容器将Servlet动态地加载到服务器上。HTTP Servlet使用HTTP请求和HTTP响应标题与客户端进行交互。因此Servlet容器支持请求和相应所用的HTTP协议。

Servlet加载过程主要分为如下两种:

懒加载模式

Servlet默认加载方式就是懒加载模式,不需要做特别设置。

当用户第一次请求这个Servlet的URL时,Servlet容器会加载Servlet Class,产生这个类的对象,调用初始化init(),调用service()方法。

用户以后在请求这个Servlet的URL时,Servlet容器就不会重复产生对象初始化了,会直接执行service()方法。

所以Servlet Class是单例模式的。

勤加载模式

懒加载模式是需要用户请求时才加载当前Servlet,而勤加载模式会在服务器启动时就加载Servlet Class,产生对象并初始化,以后请求时(包括第一次请求),都只执行service()方法。勤加载需要在web.xml中进行设置。

<servlet>
  <servlet-name>guanwei</servlet-name>
  <servlet-class>com.dailyblue.java.controller.GuanWeiController</servlet-class>
  <!--设置当前Servlet是勤加载模式,1代表加载顺序,数字越小越先加载-->
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>guanwei</servlet-name>
  <url-pattern>/guanwei</url-pattern>
</servlet-mapping>

Servlet生命周期

Servlet的生命周期包括即Servlet从创建到销毁的这一个过程,可以将Servlet的生命周期分为加载、初始化、服务、销毁这四个阶段。

加载

分为懒加载和勤加载,就是Servlet容器加载Servlet Class的过程。

初始化

Servlet容器会在浏览器第一次访问Servlet,或服务器启动的时候为该Servlet创建实例。当服务器为Servlet创建实例后,会在第一时间调用init()方法,完成Servlet的初始化操作。注意这个init()方法在Servlet的一生中,只会被服务器调用一次。

服务

当Servlet容器接收到浏览器请求时,会去调用Servlet的service()方法来处理请求,而且每次请求的时候,服务器都会调用service()方法,并且创建新的ServletRequest和ServletResponse对象并传递给service()方法,所以该方法在Servlet的一生中会被调用多次。

销毁

当服务器关闭或者当前web应用被移出服务器时,Servlet会被销毁,在销毁之前,服务器会调用destroy()方法,可以把Servlet的“临终遗言“放在该方法中,例如把对某些资源的释放等代码放在destroy()方法中。 

在Servlet中使用内置对象

通过反射实现公共Servlet

下边跟着关为一起学习四种会话跟踪技术---Servlet 入门到精通(五) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值