Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)

Servlet概述

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

简单的说,Setvlet就是应用在服务端的java程序

Servlert的作用

  1. 读取客户端(浏览器)发送的显式数据。包括网页上的HTML表单,或者也可以是来自applet或自定义的HTTP客户端程序的表单
  2. 读取客户端(浏览器)发送的隐式的Http请求数据。包括cookies,session等
  3. 处理数据并生成结果。这一阶段可能需要访问数据库,访问Web服务,或者直接计算得出对应的响应
  4. 发送显式的数据到客户端(浏览器)。例如文本文件(HTML或XML),二进制文件(GIF图像),Excel等
  5. 发送隐式的HTTP响应到客户端(浏览器)。例如Cookies或者缓存参数

Servlet程序入门

创建一个maven web项目
  1. 点击File,新建Project项目
    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第1张图片

  2. 选中Maven,勾上Creater from archetype选项,按照体重蓝色选中后点击Next按钮即可
    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第2张图片

  3. 依次填写groupid和artifactid后点击next即可

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第3张图片

  4. 选中提前配置好的maven,点击next

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第4张图片

  5. 输入项目名称Spring,点击Finish即可

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第5张图片

  6. 这样就创建好了一个名称为Spring的maven项目,结构如下图:

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第6张图片

实现Servlet接口

  1. 创建MyServlet类实现Servlet接口,重写5个方法,有init(初始化),service(服务),destory(销毁),getServletInfo(Servlet信息),getServletConfig(Servlet配置)
/**
 * 实现Servlet接口编写Servlet程序
 */
public class MyServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("ServletConfig");
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service");
    }

    @Override
    public String getServletInfo() {
        System.out.println("getServletInfo");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }     
}
  1. 编辑service方法,向浏览器输出Hello~~~~
 @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service");
        servletResponse.getWriter().write("hello~~~");
    }
  1. 配置web.xml文件为最新的
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Archetype Created Web Application</display-name>

     <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.cn.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>
<web-app>
  1. 关于上面的配置信息:
  • 每创建一个Servlet,我们都需要在web.xml文件中添加两个标签,和(可以将这两个标签看做是一组标签)

  • 两个标签内都会有标签,内容可以修改,但是必须保证两个标签更改后的内容必须保持一致

  • 用于配置servlet的全路径名

  • 用于配置浏览器以什么路径去访问该Servlet类,默认的路径名为/类名

    例如:MyServlet类配置的标签为/MyServlet,因此我们在浏览器上的访问路径就是

    http://主机名/web项目访问路径/MyServlet

5.部署都Tomct中,

  • 点击右上角的配置按钮,在下拉框中选中Edit Configurations

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGJvLCs8-1660621283948)(Servlet详解.assets/微信图片_20220815162249.png)]

  • 在弹出的Configurations界面中,按照图中标识的序号选中

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第7张图片

  • 点击地址栏旁边的按钮,选中需要的Tomcat版本号

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第8张图片

  • 点击Deployment,按照图中序号进行操作

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第9张图片

  • 在弹出的窗口上选中MyServlet:war 或者MyServlet:war exploded

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第10张图片

  • 最后一步,依次点击apply, ok按钮,到此我们的项目就已经部署到了Tomcat服务器上

  • 启动服务器,访问自己配置的MyServlet程序

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第11张图片

Servlet的调用过程

思考:上一节我们通过浏览器访问服务器中的MyServlet,可以在页面上看到MyServlet类返回的结果,那么这个Servlet是如何被调用的呢?Servlet又是怎么被执行的?

  • 浏览器发送请求
    • 浏览器发送http请求后,根据请求行中的资源路径获知浏览器访问的是哪一个WEB应用,哪一个资源
    • 然后在web.xml中进行匹配,匹配真实的路径
  • 服务器创建对象
    • 服务器根据真实的路径,通过反射创建Servlet实例,也就是MyServlet类
  • 调用init()方法
    • MyServlet实例创建后首先要执行init()方法,进行初始化
    • 如果我们还需要新增一些功能,可以重写该方法
  • 调用service()方法
    • 然后服务器会先创建两个对象,ServletRequest请求对象和ServletResponse响应对象,用来封装浏览器的请求数据和封装向浏览器的响应数据
    • 执行完service()方法内的业务后,将响应数据放在ServletResponse响应对象发送给浏览器
  • 浏览器做出响应
    • 服务器从ServletResponse响应对象中获取要发送给浏览器的数据,按照HTTP协议规定的方式(格式)组织成响应信息,再发给浏览器,调用过程完成

Servlet的生命周期

  • 加载Servlet
    • 当我们在浏览器第一次访问Servlet的时候,Tomcat会负责创建该Servlet的实例
  • 初始化
    • 当Servlet实例化后,Tomcat会立即调用init()方法初始化对象
  • 处理请求服务
    • 当浏览器访问Servlet的时候,Tomcat会调用service()方法处理请求
  • 销毁
    • 当Tomcat关闭或者检测到Servlet从Tomcat中删除的时候会自动调用destroy()方法,让该实例释放所占用的空间
  • 卸载
    • 当Servict调用完destroy()方法后,会等待垃圾回收。如果有需要再次使用这个Servict,service()方法就会再次被调用

继承HttpServlet类

在上面我们是实现了Servlet接口后,需要实现5个方法这样太麻烦了

而接下来我们要介绍的是HttpServlet这个类,它实现了Servlet接口的所有方法,并且还在原有的基础上添加了与HTTP协议处理的一些方法,比Servlet接口更为强大

因此我们在编写Servlet的时候,只需要继承HttpServlet这个类,也就是间接的实现了Servlet接口,我们关注的只是重新我们需要的方法即可

  • 一般我们在开发的时候都是重写doGet()和doPost()方法

public class Demo1 extends HttpServlet {

     /**
     *  在我们开发的过程中,通常我们使用doGet,doGet来处理请求,
     *  但是不论是哪一种方法,处理方式都是一样的
     *  因此我们可以在doGet方法时,重新调用会doPost方法进行处理
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.getWriter().write("hello~~~");
    }
}

Servlet细节

一个已经被注册的Servlet可以被多次映射
  • ​ 同一个Servlet被映射在多个URL上

       <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>com.cn.MyServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/MyServlet</url-pattern>
        </servlet-mapping>
    
        <!--多次映射-->
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/MyServlet1</url-pattern>
        </servlet-mapping>
    
  • 无论我访问的是http://localhost:8080/MyServlet还是http://localhost:8080/MyServlet1,被调用的全部都是MyServlet这个类

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第12张图片

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第13张图片

Servlet映射的URL可以使用通配符
  • 两种格式:

    • * . 扩展名
    • / *
  • 匹配所有

       <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>com.cn.MyServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/*
        
    

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第14张图片

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第15张图片

  • 匹配扩展名为.jsp的

    
     <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>com.cn.MyServlet</servlet-class>
            <!--<load-on-startup>1</load-on-startup>-->
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>*.jsp</url-pattern>
        </servlet-mapping>
    

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第16张图片

    Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第17张图片

Servlet是单例的

上述的Servlet生命周期介绍过,如果浏览器多次对Servlet的请求,一般情况下服务器只创建一个对象,并保存在内存中,为后续的请求做准备

对于每次访问请求,Servlet都会创建一个新的HttpServletRequest对象和HttpServletResponse对象,然后将这两个对象作为参数传递给它的service()方法,service()方法再根据请求的方式调用它的doGet()或者doPost()方法

而当多个用户访问共享的Servlet的时候,服务器会为每个用户创建一个线程,因此一起访问的时候就会出现线程安全问题,对于这种情况我们可以加同步机制synchronized (对象){};

  • load-on-startup

在元素中配置这样一个标签,那么在Web应用程序启动时,服务器就会加载并创建Servlet的实例,并且调用它的初始化init()方法

  <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.cn.MyServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-evbzbkBD-1660621283952)(Servlet详解.assets/微信图片_20220815174922.png)]

作用:可以实现一些定时任务(定时写日志,定时备份数据等)

ServletConfig对象

作用

​ Web容器为每一个Servlet创建了一个ServletConfig对象。该对象用于从web.xml文件中获取配置信息。

​ 也就是说当Servlet配置了初始化参数后,Web容器在创建Servlet实例对象时,会自动的将这些初始化的参数封装到创建的ServletConfig对象中,并在调用init()方法时将ServletConfig对象传递给Servlet

测试(获取Servlet的初始化参数)
  • 在web.xml文件中为Servlet配置初始化参数

    <!--测试ServletConfig对象-->
        <servlet>
            <servlet-name>Demo2</servlet-name>
            <servlet-class>com.cn.config.Demo2</servlet-class>
            <init-param>
                <param-name>name</param-name>
                <param-value>juzi</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>Demo2</servlet-name>
            <url-pattern>/Demo2</url-pattern>
        </servlet-mapping>
    
  • 测试代码

    /**
     * ServletConfig对象
     */
    public class Demo2 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletConfig config = this.getServletConfig();
            String name = config.getInitParameter("name");
            resp.getWriter().write(name);
        }
    }
    
  • 输出结果

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第18张图片

ServletContext对象

作用

Tomcat容器在启动时,会为每个WEB应用程序创建一个ServletContext对象,代表着当前的WEB应用

由于一个WEB应用中所有的Servlet都共享着同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯

ServletContext对象通常也被称为context域对象

测试(获取web应用的初始化参数)
  • 在web.xml文件中为Servlet配置初始化参数

  • 测试代码,Demo3代码

    
    /**
     * ServletContext对象
     */
    public class Demo3 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            context.setAttribute("name","juzi");
    
        }
    }
    
  • 测试代码,Demo4代码

    
    /**
     * ServletContext对象
     */
    public class Demo4 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            Object name = context.getAttribute("name");
            System.out.println(name);
        }
    }
    
  • 输出结果,先访问请求Demo3,再访问请求Demo4

Servlet详解——第一篇(调用过程、生命周期、ServletConfig对象、ServletContext对象)_第19张图片

你可能感兴趣的:(WEB,servlet,java,前端)