Servlet详解

Servlet

Servlet是一个接口,我们负责开发这个接口的实现类,而像tomcat这样的web服务器负责根据这套接口调用我们开发的实现类的方法来处理WEB请求;

继承关系

interface jakarta.servlet.Servlet

  • 唯一子类(实现类):abstract class jakarta.servlet.GenericServlet

    • 不推荐直接实现Servlet接口;

    • Servlet中的有一些方法我们用不到,核心的方法其实就只有srevice()而已,对于其他方法我们大多数情况下不会用到,如果直接实现Srevlet接口的话代码非常难看,不简洁优雅,于是就有了GenericServlet。它是一个通用的Servlet,采用了适配器模式设计,将我们不常用的方法(init、destroy……)实现(封装)了,只有一个抽象方法*service()*来让子类实现。

    • 源码分析

      public abstract class GenericServlet implements Servlet, ServletConfig, Serializable{
          private transient ServletConfig config;
          
          //	这些方法被GenericServlet实现了(只是空实现),子类如果没有需求的话就不用去实现(重写);
          public void destroy() { }
          public String getServletInfo() { return "";}
          
         /**
           * 在init()方法中将WEB容器构造好的Servlet实例赋值给了全局变量config,同时在实现的方法:			getServletconfig()当中返回config,这样我们编写的子类可以通过getServletConfig来获取配置信息;
           *  然后调用了GenericServlet扩展的init()方法,这个扩展的方法是为了让我们有机会在Servlet实例化时编写代码,只需重写这个方法即可;
           *  因此不建议去重写init(ServletConfig config),否则会导致ServletConfig获取不到,而是建议有需求时重 写init();
           */
          public void init(ServletConfig config) throws ServletException {
              this.config = config;
              this.init();
          }  
         public ServletConfig getServletConfig() {
              return this.config;
          }
          public void init() throws ServletException {}
      
      }
      
    • 唯一子类:class jakart.servlet.http.HttpServlet

主要方法

  • void init(ServletConfig servletConfig)

    ​ 在Servlet实例化后立即被调用,用于执行一些初始化操作,比如:初始化数据库连接池、线程池……

    init方法和构造方法执行时间几乎一致,功能也类似,但是为什么还要有一个init方法呢?

    ​ 因为编写Servlet类的时候不建议程序员手动添加构造方法,这可能导致在写有参构造的时候忘记添加无参构造从而导致WEB服务器实例化实例化Servlet异常,WEb服务器是通过反射机制以及无参构造来创建Servlet的,所以init方法是有必要存在的;

    ​ 该方法只会被调用一次,不常用;

  • void service(ServletRequest servletRequest, ServletResponse servletResponse)

    Servlet核心方法,当用户发起web请求时,WEB服务器会调用这个方法来处理用户请求;

    该方法主要负责:获取请求参数、处理请求、响应结果;

  • void destroy()

    Servlet实例被销毁之前会被调用,可以在这里对资源(比如:IO流、数据库连接……)进行释放;

    只会被调用一次,不常用;

  • ServletConfig getServletConfig()

  • String getServletInfo()

    返回这个Servlet的相关信息:作者、编写时间……

    实际开发基本不用;

Servlet的定义

想要定义一个Servlet需要以下步骤:

  • 实现Servlet接口或者继承其子类:jakarta.servlet.GenericServletjakarta.servlet.http.HttpServlet
  • 如果是实现的Servlet接口:实现接口内部的抽象方法;
  • 如果是基于GenericServlet的扩展类:重写service方法;

注册Servlet

定义好的Servlet需要注册才能生效,才能被Tomcat这样的WEB服务器识别;

方式一:web.xml文件里注册

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">  
    
    一个Servlet标签对应一个Servlet类;
    <servlet>
        Servlet的别名,便于servlet-mapping标签与当前Servlet进行绑定;
        <servlet-name>forwardServlet</servlet-name>
        Servlet类的`全限定类名`;
        <servlet-class>com.nanum.ForwardServlet</servlet-class>
        servlet实例被创建时可以获取这里的初始化参数,K-V形式(可选项);
        <init-param>
            <param-name>name</param-name>
            <param-value>value</param-value>
        </init-param>
        加上该标签后WEB服务器在启动时以及web应用部署后会 立即 创建Servlet的实例;
        数字表示servlet加载的优先级,数值越小的Servlet,越会被WEB服务器优先创建实例;
		<!--<load-on-startup>1</load-on-startup>-->
    </servlet>

    1、servlet映射标签,用于为servlet配置访问路径,即URL;
    2、url-pattern标签的值的最前面切记加上`/`以表示从当前项目的根目录开始访问;
    3、一个servlet标签至少要有一个servlet-mapping标签与之匹配;
    <servlet-mapping>
        <servlet-name>forwardServlet</servlet-name>
        <url-pattern>/forwardServlet</url-pattern>
    </servlet-mapping>
</web-app>

web.xml在项目部署到Tomcat时被Tomcat加载,然后Tomcat根据web.xml文件里配置的Servlet信息,通过反射机制来创建Servlet;

方式二:使用注解注册

冒号里面的内容就是`url-pattern`的值,也就是当前Servlet的访问地址;
也可以传入数组为当前servlet配置多个访问地址:{"/mainServlet","/other"}
@WebServlet("/mainServlet")
public class MainServlet extends HttpServlet {
}

用注解的方式配置servlet是在servlet3.0之后新增的特性,用于简化servlet、Filter、Listener的声明

Servlet的生命周期

当web应用部署到WEB服务器之后,WEB服务器会立即加载并解析web应用中的web.xml,获取Servlet的配置信息,但是默认不会立即实例化Servlet。只有当Servlet被访问的时候WEB服务器才会实例化Servlet;

WEB服务器实例化Servlet是通过Servlet的无参构造函数实现的,所以编写Servlet的时候请务必保证提供无参构造函数;

Servlet只会被WEB服务器创建一个实例,所它是单例的;

  • 首先WEB服务器在创建Servlet实例之后会调用init(ServletConfig servletConfig)方法来初始化Servlet;

    通过参数ServletConfig可以获取像我们写在web.xml里的init-param这样的配置信息来完成Servlet的初始化工作;

  • 然后这个Servlet实例就在WEB服务器(WEB Server)的内存当中,直到WEB服务器收到Servlet的WEB请求,这时WEB服务器会调用service()方法处理请求以及响应结果。每发送一次请求,这个方法就会被调用一次;

  • 最后Servlet实例里被销毁时调用destroy()方法;

    ​ a)Servlet实例长时间不被访问会被GC销毁;

    ​ b)服务器关闭时会销毁所有Servlet实例;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值