zoukankan      html  css  js  c++  java
  • 【Servlet】(1)Servlet简介、Servlet底层原理、Servlet实现方式、Servlet生命周期

     

    一、Servlet简介

    1、Servlet定义:

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

    2、Servlet定义:

    A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol. 
    (servlet是一个java小程序运行在web服务器。servlet接收并响应来自Web客户端的请求,通常通过HTTP,超文本传输协议。)

    3、Servlet实现过程:

    (1)客户端发送请求至服务器端;

    (2)服务器将请求信息发送至 Servlet;

    (3)Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;

    (4)服务器将响应返回给客户端。

    4、Servlet可以完成以下任务:

    (1)动态生成HTML文档。

    (2)将请求转发给Servlet组件。

    (3)读取客户端的Cookie,以及向客户端写入Cookie。

    (4)访问服务器的资源,如数据库、 XML、文件对像等。

    5、Servlet的特点:

    (1)Servlet对像,由Servlet容器(Tomcat)创建。

    (2)Servlet是一个接口:位于javax.servlet包中。

    (3)service方法用于接收用户的请求并返回响应。

    (4)用户访问时多次被执行(可以统计网站的访问量)。

    二、Servlet底层原理:

    1、javax.servlet Interface Servlet

    这里写图片描述

    2、javax.servlet Interface Servlet 中的method

    这里写图片描述

    3、Servlet接口、GenericServlet类、HttpServlet类三者之间的关系

    这里写图片描述

    三、Servlet实现方式

    1、Servlet的实现方式一(实现Servlet接口):

    Servlet接口:

    这里写图片描述

    package cn.hncu;
    
    import java.io.IOException;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class FirstServlet implements Servlet {
        /**init方法*/
        @Override
        public void init(ServletConfig paramServletConfig) throws ServletException {
        }
    
        /**getServletConfig方法*/
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        /**service方法*/
        @Override
        public void service(ServletRequest paramServletRequest,
                ServletResponse paramServletResponse) throws ServletException,
                IOException {
        }
    
        /**getServletInfo方法*/
        @Override
        public String getServletInfo() {
            return null;
        }
    
        /**destroy方法*/
        @Override
        public void destroy() {
        }
    }

    2、Servlet的实现方式二(继承GenericServlet类):

    GenericServlet类:

    这里写图片描述

    package cn.hncu;
    
    import java.io.IOException;
    
    import javax.servlet.GenericServlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    /**【注意】GenericServlet是抽象类,service是抽象方法*/
    public class ExtendGenericServlet extends GenericServlet {
    
        /**service方法*/
        /**【注意】唯独service方法没有被实现,这个service方法我们自己使用*/
        @Override
        public void service(ServletRequest paramServletRequest,
                ServletResponse paramServletResponse) throws ServletException,
                IOException {
        }
    
        /**destroy方法*/
        /**【注意】除过service方法之外,其他方法都已经被实现了,并且这些方法都调用父接口的方法*/
        @Override
        public void destroy() {
            super.destroy();
        }
    
        /**getServletConfig方法*/
        @Override
        public ServletConfig getServletConfig() {
            return super.getServletConfig();
        }
    
        /**getServletInfo方法*/
        @Override
        public String getServletInfo() {
            return super.getServletInfo();
        }
    
        /**init方法*/
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
        }
    
        /**【注意】:如果我们覆盖带参数的init父类方法时候,没有写super.init(config)这一句:
        public void init(ServletConfig config) throws ServletException {
        }
    
        我们的程序会出现空指针异常错误:
        严重: Servlet.service() for servlet [ExtendsGenericServlet] in context with path [/useServlet] threw exception
    java.lang.NullPointerException
        at javax.servlet.GenericServlet.getInitParameterNames(GenericServlet.java:99)
        at cn.hncu.ExtendsGenericServlet.service(ExtendsGenericServlet.java:53)
    
        我们知道,此时getInitParameterNames是空指针,我们去API中查看,关于getInitParameterNames的来源,
        如果来源的某一地方是空指针,则就说明这个地方值为空!
    
        我们依次点击这些类的关联:
    
         public Enumeration<String> getInitParameterNames()
         {
             return getServletConfig().getInitParameterNames();
         }
         ----》说明:getServletConfig()为NULL
    
         public ServletConfig getServletConfig()
         {
             return this.config;
         }
         ----》说明:config为NULL
    
        public void init(ServletConfig config)
        throws ServletException
        {
           this.config = config;
           init();
        }
        ----》说明:此处就是问题的根源:config没有赋值
    
        ----》也说明:带参数的init方法没有被执行
    
        ----》因为我们在父类方法的时候,正好将父类的方法:init(config)给删除了
    
        ----》所以覆盖父类方法的时候这句一定要写!
    
    
    //GenericServlet类中有一个空参init()方法,
    
    //其实是适配器模式中的一个技术细节:在带参init方法中帮我们把config赋好值,
    
    //然后调用空参且空实现init()方法--该方法是专门给子类覆盖的。
    
    //---在适配器中帮我们做一部分事情,然后调用我们的覆盖方法
    
    }

    2、Servlet的实现方式三(继承HttpServlet类):

    HttpServlet类:

    这里写图片描述

    package cn.hncu;
    
    
    import java.io.IOException;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ExtendHttpServlet extends HttpServlet {
    
        /**service方法*/
        /**【注意】此service方法是HttpServlet类 继承 GenericServlet类 后实现的其抽象service方法的*/
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            super.service(req, resp);
        }
    
        /**destroy方法*/
        /**【注意】下面的这些方法全部是继承与GenericServlet类中的方法*/
        @Override
        public void destroy() {
            super.destroy();
        }
    
        /**getServletConfig方法*/
        @Override
        public ServletConfig getServletConfig() {
            return super.getServletConfig();
        }
    
        /**getServletInfo方法*/
        @Override
        public String getServletInfo() {
            return super.getServletInfo();
        }
    
        /**init方法*/
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
        }
    }
    

    四、Servlet生命周期

    1、在JavaWeb项目中测试Servlet的生命周期

    (1)init方法:

    只会被初始化一次,由容器初始化,初始化成功后将缓存与容器中。 
    它的初始时间分为两种: 
    用户第一次访问时。 
    服务器启动时,需要配置。

    (2)service方法:

    每次请求都会访问此方法。 
    每次请求都会创建新的Request和Response对像。

    (3)destory方法:

    当服务器关闭时由容器调用并销毁。

    2、JavaWeb项目—-TestServlet project

    (1)、TestServlet框架:

    这里写图片描述

    (2)、index.jsp:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
       <title>测试Servlet的生命周期</title>
      </head>
      <body>
        <h2>测试Servlet的生命周期</h2>
        <a href="servlet/TestServlet">测试servlet的生命周期</a>
      </body>
    </html>

    (3)、TestServlet.java:

    package cn.hncu;
    
    
    import java.io.IOException;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    /**
     * 用于测试Servlet的生命周期
     * @author user
     *
     */
    public class TestServlet implements Servlet {
            /***
            【注意】这里是我们自己实现的Servlet接口,因此每个方法的返回值都是我们自己决定的。
            由于另一个方法中getServletConfig()中返回值是NULL,因此需要将init方法中的ServletConfig参数赋值给getServletConfig的结果。
            即:我们定义私有类成员变量:config
            在init方法中让:this.config=paramServletConfig;
            */
        private ServletConfig config;
    
        @Override
        public void init(ServletConfig paramServletConfig) throws ServletException {
            this.config=paramServletConfig;
            System.out.println("init方法执行....");
        }
    
        @Override
        public ServletConfig getServletConfig() {
            System.out.println("getServletConfig方法执行....");
            return config;
        }
    
        @Override
        public void service(ServletRequest paramServletRequest,
                ServletResponse paramServletResponse) throws ServletException,
                IOException {
            System.out.println("service方法执行....");
            ServletConfig config = getServletConfig();
            String info = getServletInfo();
        }
    
        @Override
        public String getServletInfo() {
            System.out.println("getServletInfo方法执行");
            return null;
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy方法执行....");
        }
    }
    

    4、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></display-name>
      <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>cn.hncu.TestServlet</servlet-class>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/servlet/TestServlet</url-pattern>
      </servlet-mapping>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    

    5、执行结果:

    这里写图片描述

    6、也可以修改配置文件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></display-name>
      <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>cn.hncu.TestServlet</servlet-class>
        <!-- 
        在启动在启动时加载元件负载指示就加载这个servlet(实例化并调用其())对Web应用程序的启动。
        这些元素的可选内容必须是一个整数,指示应加载servlet的顺序。
        如果值是负整数,或者元素不存在,容器可以自由加载servlet。
        如果该值是正整数或0,则容器必须在部署应用程序时加载和初始化servlet。
        容器必须保证servlet标有低整数在servlet标有高整数装。
        容器可选择顺序加载Servlet具有相同的负载启动值。
         -->
        <load-on-startup>20</load-on-startup>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/servlet/TestServlet</url-pattern>
      </servlet-mapping>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    

    7、修改web.xml后:

    这里写图片描述

  • 相关阅读:
    apt update ,apt upgrade 和 apt dist-upgrade 的区别
    CVE-2018-8639 简单利用 win7
    如何拆解性能测试需求
    博客搬家啦
    驱动开发学习一
    驱动开发基础之数据结构
    c++容器加迭代器和python装饰器的对比
    c++简单学习
    windows下z3安装
    switch反汇编
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/10583828.html
Copyright © 2011-2022 走看看