Servlet详解

一、前言

备注:该技术博客的内容是我根据技术视频整理与总结的(并非复制粘贴)。原视频源于黑马JavaWeb课程

二、概述

Servlet再Javaweb中显得特别重要,整个Javaweb核心知识体系都是围绕servlet转的。一定要重点掌握。虽然很重要,但是并不难。

首先介绍一下什么是servlet:
servlet是由两个单词拼接而成(server applet)直译过来就是运行在服务器端的小程序servlet就是一个接口(定义了一些方法),定义了Java类被浏览器访问到(tomcat识别)的规则。将来我们自定义一个类实现这个servlet接口重写它的方法,就可以被tomcat识别。我们将这个类称为Servlet

我们用一张图来理解一下:
Servlet详解_第1张图片

三、快速入门

  1. 创建JavaEE项目
  2. 定义一个类,必须实现Servlet接口
public class ServletDemo1 implements Servlet
  1. 重写接口中的抽象方法
  2. 配置Servlet:为什么?因为类定义好了,将来通过浏览器访问Servlet,浏览器要通过url访问。比如说路径为:localhost:8080/day13_tomcat/demo。我们需要这个资源名称(/demo)找到Java类,所以我们需要把Java类映射成这个路径,所以需要配置一下。

怎么配置Serlvet呢?当然是在web-xml文件中的根标签(web-app) 中配置:

Servlet详解_第2张图片
代码如下:


    <servlet>
        <servlet-name>demo1servlet-name>  				  (随便起个名字)
        <servlet-class>cn.itcast.web.servlet.ServletDemo1servlet-class> (全类名)
    servlet>

    <servlet-mapping>		 (做一个映射) 
        <servlet-name>demo1servlet-name>	 (对应上面的名字)
        <url-pattern>/demo1url-pattern>	  (资源路径)
    servlet-mapping>

配置完成之后我们重新连接Tomcat服务器运行,然后在页面中输出:http://localhost:8080/demo1
回到控制台可以发现,自动调用了service方法

Servlet详解_第3张图片

四、Servlet执行原理

讲解完Servlet快速入门之后,我们发现我们定义一个类,这个类我们并没有创建对象,也没有调用它的方法,它竟然自动被执行了。为什么?

我们已画图的方式来讲解:

Servlet详解_第4张图片
根据上图我们来分析:

首先我们通过localhost:8080找到了具体某个主机,以及某个应用程序(根据8080找到Tomcat)
通过day13_tomcat可以找到当前tomcat下部署的这个项目(根据虚拟目录找到项目)。找到项目后接下来跟个资源名称 /demo1 。tomcat内部会做一个检索的操作,会查找web.xml文件中是否有url-patten 是/demo1,它会自己解析xml文件。

突然发现找到/demo1了,发现资源路径是一样的。然后通过/demo1这个路径找到了servlet-name的demo1 ,进而找到全类名(cn.itcast.web.servlet.ServletDemo1)。只要看到全类名在配置文件中存在,第一件事就要想到反射

接下来tomcat进行了一些操作:

  1. tomcat将全类名对应的字节码文件加载进内存(Class.forname();
  2. 创建对象 cls.newInstance()
  3. 调用方法 service()

那么Tomcat怎么知道这个类中一定有一个方法叫做service呢?因为我们实现了Servlet接口,这个接口一定会有service方法。如果我们不重写service方法,这个类编译都不会通过的。tomcat一定知道这个类中有service方法,所以调用service方法。

所以我们以后不需要创建Servlet实现类对象,也不需要调方法。我们只需要按照人家规定的方法结构,把方法实现了,在里面编写我们想要的逻辑就可以了。(对象的创建,方法的调用都是由Tomcat服务器执行的

也就是说,Servlet的运行要依赖web容器(tomcat就是一个web容器)。不在这个容器中,就没人帮Servlet创建对象,调用方法,就没法运行了。这就是我们所说的Servlet实现原理

上述总结:

  1. 当服务器接收到客户端的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件是否有url-pattern标签体内容与资源路径一致
  3. 如果有,则在找到对应的servlet-class标签对应的全类名
  4. tomcat会将字节码文件加载进内存中,并且创建其对象
  5. 调用其方法(至于调用什么方法,我们以后再说什么时候调用什么方法,现在可以暂且理解为调用service方法)

五、生命周期方法

分析完执行原理之后,接下来聊聊Servlet中的方法。这个方法会涉及到Servlet中的知识点,就是Servlet中的生命周期方法

  1. 被创建:执行init方法,只执行一次(因为Servlet只会被创建一次)
  2. 提供服务:执行service方法,执行多次
  3. 被销毁:执行destroy方法,执行一次(因为Servlet只会被杀死一次)
package cn.itcast.web.servlet;

import javax.servlet.*;
import java.io.IOException;


//Servlet的方法
public class ServletDemo2 implements Servlet {
     
    /**
     * 初始化方法
     * 在Servlet被创建时,执行。只会执行一次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
     
        System.out.println("init....");
    }

    /**
     * 获取ServletConfig对象(了解即可)
     * ServletConfig:Servlet的配置对象
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
     
        return null; 
    }

    /**
     * 提供服务方法
     * 每一次Servlet被访问时候执行。执行多次
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
     
        System.out.println("service....");
    }

    /**
     * 获取Servlet的一些信息,版本,作者等...(了解即可)
     * @return
     */
    @Override
    public String getServletInfo() {
     
        return null;
    }

    /**
     * 销毁方法
     * 在服务器正常关闭时候执行,执行一次
     */
    @Override
    public void destroy() {
     
        System.out.println("destroy....");
    }

}

六.生命周期详解

介绍了Servlet中5个方法,我们重点介绍了生命周期相关的三个方法。接下来我们就对生命周期中一些特点,做一个阐述:

  1. 被创建:执行init方法,只执行一次(因为Servlet只会被创建一次)
    该方法只执行一次,说明Servlet在内存中只存在一个对象,Servlet是单例的
    init方法用于加载资源

多个用户同时访问时,可能存在线程安全问题。(不能用锁机制,性能影响严重)
解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对其修改值。

Servlet什么时候创建?
默认情况下,第一次被访问时,Servlet被创建
我们可以去配置指定Servlet创建时机,在servlet标签下配置load-on-startup


    <servlet>
        <servlet-name>demo2servlet-name>
        <servlet-class>cn.itcast.web.servlet.ServletDemo2servlet-class>

        
        <load-on-startup>-5load-on-startup>
    servlet>
  1. 提供服务:执行service方法,执行多次
    每次访问Servlet时,service方法都会被调用一次

  2. 被销毁:执行destroy方法,执行一次(因为Servlet只会被杀死一次)

Servlet被销毁之前,执行destory方法,一般用于释放资源
服务器被关闭时,Servlet被销毁。
只有服务器正常关闭时,才会执行destory方法。

七、Servlet3.0注解配置

我们可以发现快速入门中的第四步配置Servlet很麻烦,将来写一个Servlet就要配置一次。但是一个项目可能会有几百个Servlet,需要在web.xml配置文件中配很多,而且非常的混乱。

所以要解决这个问题,官方给我提供一个新的标准:就是Servlet3.0
3.0版本最大的好处就是支持注解配置。可以不需要web.xml了。
Servlet详解_第5张图片

步骤:

  1. 创建JavaEE项目,选择Servlet版本3.0以上,可以不创建web.xml
  2. 定义一个类,实现Servlet接口
  3. 重写方法
  4. 在类上使用@webServlet注解进行配置

@WebServlet(“资源路径(也就是url-patten)”)

Servlet详解_第6张图片
将来我们写具体Servlet代码时候,就使用注解配置,别去用配置文件web.xml

八、IDEA和tomcat相关配置

介绍完使用注解方式对Servlet进行配置,接下来说一下idea与tomcat相关配置。
讲这个配置是为了方便大家后期更好的使用IDEA和Tomcat集成。

  1. IDEA会为每一个Tomcat部署的项目单独建立一份配置文件

查看控制台的log:

Using CATALINA_BASE: “C:\Users\XuZhibin\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat_untitled8_2”

  1. 工作空间项目 和 Tomcat部署的web项目

tomcat真正访问的是Tomcat部署的web项目,这个项目对应着工作空间项目的web目录下的所有资源
WEB-INF目录下的资源不能被浏览器直接访问

  1. 断点调试:使用“小虫子(debug)”启动

九、Servlet体系结构

Servlet接口有两个实现类(GenericServlet,HttpServlet)
GenericServlet实现了Servlet接口,它是一个抽象类
HttpServlet继承了GenericServlet,它也是一个抽象类

首先来说GenericServlet。将来如果我去写一个Servlet,我可以不去实现这个Servlet接口,直接继承GenericServlet也是可以的。

1.GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象。
也就是说将来定义Servlet类时,可以继承GenericServelt类实现service()方法即可

@WebServlet("/demo2")
public class ServletDemo2 extends GenericServlet {
     
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
     
        System.out.println("demo2.....");
    }
}

这是第二种方式,但是我们还是不用(第一种方式实现Servlet接口)。

2.我们用HttpServlet类
Servlet详解_第7张图片
将来如果想去屏蔽GET/POST请求方式的处理逻辑,我们可以去继承HttpSerlet类,并且去重写doGet方法和doPost方法就可以了。因为将来都是调用service方法,该方法会做方法分发,你是get就调用doGet,你是post就会调用doPost。

HttpServlet类:对http协议的一种封装,简化操作。

使用步骤如下:

  1. 定义类去继承HttpServlet
  2. 重写doGet / doPost方法
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
     
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        System.out.println("doGet.....");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        System.out.println("doPost.....");
    }
}

十、urlpatten配置

  1. urlpatten:Servlet访问路径

一个Servlet可以定义多个访问路径

@WebServlet({"/d4","/dd4","/ddd4"})

路径的定义规则:

  1. /xxx
  2. /xxx/xxx :多层路径,目录结构
  3. *.do

你可能感兴趣的:(JavaWeb博客,java,servlet,tomcat,web服务器,spring)