zoukankan      html  css  js  c++  java
  • servlet生命周期

    1. 生命周期

    我们之前使用的都是javax.servlet.http.HttpServlet,这个类实现了javax.servlet.Servlet接口,而这个接口中定义的三个方法是所有servlet都必须实现的。

    package javax.servlet;
    
    public interface Servlet {
    
        void init(ServletConfig config);
    
        void service(ServletRequest request, ServletResponse response);
    
        void destroy();
    
    }

    如图所示,tomcat之类的服务器首先根据web.xml中的定义实例化servlet,然后调用它的init()方法进行初始化,init()方法的ServletConfig参数是服务器传递进servlet的,其中包含web.xml配置的初始化信息和ServletContext对象等共享内容。

    初始化后的servlet实例便进入等待请求的状态,当有与servlet-mapping匹配的请求进入时,服务器会调用servlet实例的service方法,传入ServletRequest与ServletResponse两个参数等待servlet处理完毕。

    注意一点,对于每个web应用,内存中只存在一个servlet实例,所有请求都是调用这个servlet实例,所以我们说servlet不是线程安全的,所有操作都要限制在service()方法中进行,不要在servlet中定义类变量。(doGet()和doPost()是HttpServlet覆盖service()方法后分支出来的辅助方法,实际上服务器调用的还是service()。)

    当web应用卸载时,服务器会调用每个已经初始化的servlet的destroy(),然后销毁这些servlet实例,如果你需要在servlet销毁时释放什么资源的话,可以写在destory()方法中。

    那么servlet是在什么时候进行初始化的呢?我们可以通过web.xml中的load-on-startup标签。

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>anni.TestServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    load-on-startup的值是一个整数,当它大于等于零的时候服务器会在web发布的时候初始化servlet。当它小于零或者我们没有设置load-on-startup的时候,服务器会在用户第一次访问servlet的时候才去初始化servlet。

    或许你对load-on-startup为什么是一个整数存有疑问,为什么不是true和false呢?这是因为如果我们在web.xml中设置了多个servlet的时候,可以使用load-on-startup来指定servlet的加载顺序,服务器会根据load-on-startup的大小依次对servlet进行初始化。不过即使我们将load-on-startup设置重复也不会出现异常,服务器会自己决定初始化顺序。

    回头看看javax.servlet.Filter中也有init()和destroy()方法,它的声明周期与servlet基本一致,服务器使用init()对Filter初始化,销毁Filter的时候调用destroy()方法,只是过滤器就不在有load-on-startup设置了,它总是会在服务器启动的时候进行初始化,然后按照web.xml定义的顺序依次执行。

    2. jsp九大默认对象

    分别是request, response, out, pageContext, session, application, page, config, exception。

    让我们看看它们与servlet中变量的对应关系。

    首先要明确的是,这九个变量都只在<%%>中有效,<%!%>中是无法调用这九个对象的。实际上<%%>最后会成为service()方法中的代码,我们这里就看看如何在service()方法中获得这些对象吧。

    1. request

      public void service(ServletRequest req, ServletResponse res) {
          HttpServletRequest request  = (HttpServletRequest) req;
      }
      
                      

      jsp中的request就是service()中传入的req参数,因为service中定义的是ServletRequest类型,我们还需要转换成HttpServletRequest类型。

    2. response

      public void service(ServletRequest req, ServletResponse res) {
          HttpServletResponse response  = (HttpServletResponse) res;
      }
      
                      

      与上例相同,response也是service()中传入的res参数。

    3. out

      Writer out = response.getWriter();
                      

      out对应着从response中取出的writer对象,负责向响应中输出数据。不过jsp和servlet中的out还是有一点区别,虽然它们都实现了java.io.Writer接口,但servlet中实际类型是java.io.PrintWriter,而jsp中实际类型是javax.servlet.jsp.JspWriter。

    4. pageContext

      这是jsp独有的,servlet里没有page的概念。

    5. session

      HttpSession session = request.getSession();
                      

      直接从request中获得会话。

    6. application

      ServletConext application = getServletConfig().getServletContext();
                      

      可以通过servletConfig获得ServletContext,这是整个web应用共享的一个对象。

    7. page

      Object page = this;
                      

      page就代表当前jsp对象,也可以直接使用this引用。

    8. config

      ServletConfig config = getServletConfig();
                      

      这是在servlet初始化时由服务器传入的对象,可以通过它获得web.xml中定义的初始化参数。

    9. exception

      想在jsp中使用这个对象需要满足一些条件了。

      首先我们要在14-05/index.jsp中故意抛出一个异常。

      <%@ page contentType="text/html; charset=gb2312" errorPage="error.jsp"%>
      <%
          String str = null;
          str.length();
      %>
                      

      str值是null,直接在null上调用length()方法会引发NullPointerException,然后我们可以看到页面第一行使用jsp指令(directive)设置了errorPage="error.jsp",这样在出现异常的时候就会自动forward到error.jsp中。现在看看error.jsp中有些什么。

      <%@ page contentType="text/html; charset=gb2312" isErrorPage="true"%>
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
      <html>
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
              <title>index</title>
          </head>
          <body>
              <%=exception%>
          </body>
      </html>
                      

      最主要的是在jsp指令(directive)中设置isErrorPage="true",这样我们就可以在jsp中使用exception对象了,实际上这个异常是从request中取出来的。

    到此为止,jsp九大默认对象已经讲解完毕,其中常用的还是四个作用域对应的对象,其他的了解即可。

  • 相关阅读:
    MySQL体系结构
    详解MySQL的用户密码过期/锁定解锁功能
    MySQL5.7 密码安全策略
    Python终端如何输出彩色字体
    flashback
    PXC 部署前置检查
    CentOS7 安装docker
    CentOS7 安装ifconfig
    CentOS 7 网络配置
    VMware虚拟机克隆Linux系统引起的网卡问题
  • 原文地址:https://www.cnblogs.com/wenjieyatou/p/6112460.html
Copyright © 2011-2022 走看看