zoukankan      html  css  js  c++  java
  • servlet分析

    Servlet生命周期分为三个阶段:

      1,初始化阶段  调用init()方法

      2,响应客户请求阶段  调用service()方法

      3,终止阶段  调用destroy()方法

    Servlet初始化阶段:

      在下列时刻Servlet容器装载Servlet:

        1,Servlet容器启动时自动装载某些Servlet,实现它只需要在web.XML文件中的<Servlet></Servlet>之间添加如下代码:

    <loadon-startup>1</loadon-startup>

        2,在Servlet容器启动后,客户首次向Servlet发送请求

        3,Servlet类文件被更新后,重新装载Servlet

      Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。

        

    Servlet工作原理:

      首先简单解释一下Servlet接收和响应客户请求的过程,首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,通过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet,doPost等等这些方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。

      每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。

      Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest,ServletResponse强转为HttpRequest和HttpResponse。

    @Override
    public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException {

    HttpServletRequest request;
    HttpServletResponse response;

    try {
    request = (HttpServletRequest) req;
    response = (HttpServletResponse) res;
    } catch (ClassCastException e) {
    throw new ServletException("non-HTTP request or response");
    }
    service(request, response);
    }
    }

    代码的最后调用了HTTPServlet自己的service(request,response)方法,然后根据请求去调用对应的doXXX方法,因为HttpServlet中的doXXX方法都是返回错误信息,

    所以需要我们在自定义的Servlet中override这些方法!

    Servlet响应请求阶段:

      对于用户到达Servlet的请求,Servlet容器会创建特定于这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet的service方法。service方法从ServletRequest对象获得客户请求信息,处理该请求,并通过ServletResponse对象向客户返回响应信息。

      对于Tomcat来说,它会将传递过来的参数放在一个Hashtable中,该Hashtable的定义是:

    private Hashtable<String String[]> paramHashStringArray = new Hashtable<String String[]>();

      这是一个String-->String[]的键值映射。

      HashMap线程不安全的,Hashtable线程安全。

    -----------------------------------------------------------------------------------------------------------------------------------

    Servlet终止阶段:

      当WEB应用被终止,或Servlet容器终止运行,或Servlet容器重新装载Servlet新实例时,Servlet容器会先调用Servlet的destroy()方法,在destroy()方法中可以释放掉Servlet所占用的资源。

    Servlet与JSP的比较:

      有许多相似之处,都可以生成动态网页。

      JSP的优点是擅长于网页制作,生成动态页面比较直观,缺点是不容易跟踪与排错。

      Servlet是纯Java语言,擅长于处理流程和业务逻辑,缺点是生成动态网页不直观。

    ---------------------------------------------------------------------------------------------------------------------------------------

    Servlet

    Servlet 没有 main 方法,不能够独立的运行,它的运行需要容器的支持,Tomcat 是最常用的 JSP/Servlet 容器。
    Servlet 运行在 Servlet 容器中,并由容器管理从创建到销毁的整个过程。

    Servlet 的生命周期

    (1) 加载和实例化
    Servlet 容器装载和实例化一个 Servlet。创建出该 Servlet 类的一个实例。
    (2) 初始化
    在 Servlet 实例化完成之后,容器负责调用该 Servlet 实例的 init() 方法,在处理用户请求之前,来做一些额外的初始化工作。
    (3) 处理请求
    当 Servlet 容器接收到一个 Servlet 请求时,便运行与之对应的 Servlet 实例的 service() 方法,service() 方法再派遣运行与请求相对应的 
    doXX(doGet,doPost) 方法来处理用户请求。
    (4) 销毁
    当 Servlet 容器决定将一个 Servlet 从服务器中移除时 ( 如 Servlet 文件被更新 ),便调用该 Servlet 实例的 destroy() 方法,在销毁该 Servlet 实例之前,
    来做一些其他的工作。
    其中,(1)(2)(4) 在 Servlet 的整个生命周期中只会被执行一次。

    Servlet 的工作原理

    结合右边给出的流程图:
    当客户端浏览器向服务器请求一个 Servlet 时,服务器收到该请求后,首先到容器中检索与请求
    匹配的 Servlet 实例是否已经存在。若不存在,则 Servlet 容器负责加载并实例化出该类 Servlet
    的一个实例对象,接着容器框架负责调用该实例的 init() 方法来对实例做一些初始化工作,然后
    Servlet 容器运行该实例的 service() 方法。
    若 Servlet 实例已经存在,则容器框架直接调用该实例的 service() 方法。
    service() 方法在运行时,自动派遣运行与用户请求相对应的 doXX() 方法来响应用户发起的请求。
    通常,每个 Servlet 类在容器中只存在一个实例,每当请求到来时,则分配一条线程来处理该请求。








    JSP 工作原理

    结合右边给出的流程图:
    当客户端浏览器向服务器请求一个 JSP 页面时,服务器收到该请求后,首先检查所请求的这个
    JSP 文件内容 ( 代码 ) 是否已经被更新,或者是否是 JSP 文件创建后的第一次被访问,如果是,
    那么,这个 JSP 文件就会在服务器端的 JSP 引擎作用下转化为一个 Servlet 类的 Java 源代码
    文件。紧接着,这个 Servlet 类会在 Java 编译器的作用下被编译成一个字节码文件,并装载
    到 jvm 解释执行。剩下的就等同于 Servlet 的处理过程了。
    如果被请求的 JSP 文件内容 ( 代码 ) 没有被修改,那么它的处理过程也等同于一个 Servlet 的
    处理过程。即直接由服务器检索出与之对应的 Servlet 实例来处理。

    需要注意的是,JSP 文件不是在服务器启动的时候转换成 Servlet 类的。而是在被客户端访问
    的时候才可能发生转换的 ( 如 JSP 文件内容没有被更新等,就不再发生 Servlet 转换 )。
    就 Tomcat 而言,打开目录 %Tomcat%/work/%您的工程文件目录%,然后会看到里面有 3
    个子目录:org/apache/jsp,若没有这 3 个目录,说明项目的 JSP 文件还没有被访问过,
    打开进到 jsp 目录下,会看到一些 *_jsp.java 和 *_jsp.class 文件,这就是 JSP 文件被转换成
    Servlet 类的源文件和字节码文件了。
    有兴趣的话,可以使用浏览器访问服务器中的 JSP,然后观察 JSP 转换 Servlet 以及编译的时机。

    Servlet 与 JSP

    JSP 本质是一个 Servlet,它的运行也需要容器的支持。
    在 JSP 和 Servlet 文件中都可以编写 Java 和 HTML 代码,不同的是,
    Servlet 虽然也可以动态的生成页面内容,但更加偏向于逻辑的控制。
    JSP 最终被转换成 Servlet 在 jvm 中解释执行,在 JSP 中虽然也可以编写 Java 代码,但它更加偏向于页面视图的展现。
    在 MVC 架构模式中,就 JSP 和 Servlet 而言,C 通常由 Servlet 充当,V 通常由 JSP 来充当。

    ---------------------------------------------------------------------------------------------------------------------

    一:servlet定义

    Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序。

    二:简单servlet实例

    //导入所需的包

    import javax.servlet.http.*;

    import javax.servlet.*;

    import java.io.*;

    public class FirstServlet extends HttpServlet {

    //处理请求的方法

    public void doGet(HttpServletRequest req, HttpServletResponse resp)

    throws ServletException, java.io.IOException {

    //数据发送给客户端—>控制台方式输出

    //System.out.println(“Hello Servlet”);

    //数据发送给客户端—>HTML页面输出

    resp.setContentType(“text/html”);

    resp.getWriter().print(“<html>”);

    resp.getWriter().print(“<head>”);

    resp.getWriter().print(“</head>”);

    resp.getWriter().print(“<body>”);

    resp.getWriter().print(“Hello World”);

    resp.getWriter().print(“</body>”);

    resp.getWriter().print(“</html>”);

    }

    }

    三:servlet配置到Tomcat中去

    Tomcat是一个web容器,也叫web服务器。我们都知道J2EE有十三个标准,这些标准大部分都是接口,Tomcat只是实现了JSP 和 servlet 开发标准。实现了所有的开发标准,就是应用程序服务器,比如Jboss。

    编译好的servlet类只能运行在tomcat容器中,客户端浏览器不可以直接访问Servlet,需要在web.xml中配置一下

    <servlet>

    <servlet-name>FirstServlet</servlet-name>

    <servlet-class>FirstServlet</servlet-class>

    </servlet>

    <servlet-mapping>

    <servlet-name>FirstServlet</servlet-name>

    <url-pattern>/servlet/FirstServlet</url-pattern>

    </servlet-mapping>

    Tomcat启动成功后,在浏览器中输入:http://localhost:8080/abingtest/servlet/FirstServlet

    四:servlet运行原理

    当我们在浏览器中输入http://localhost:8080/abingtest/servlet/FirstServlet的时候,Tomcat是如何找到我们的servlet ,运行,并返回我们想看到的页面的呢。

    1. WebApplication的标准目录结构:

    WEB-INF/classes

    /lib

    Web.xml

    也就是一个完整的web应用程序目录下,必须包含以上的目录结构。

    Classes 文件夹下是项目中用到的类文件,均由JDK编译成了.class文件

    Lib文件夹是我们项目中引用的jar包

    Web.xml是整个web应用程序的配置文档。

    了解了这些,我们再来看Tomcat的工作流程。

    2. Tomcat解析URL

    a) 首先来看URL中包含的信息:”协议” + “端口号” + “路径(项目名称+文件路径)”

    Tomcat启动后,监听我们的8080端口,当有Url请求发过来之后,解析出项目名称 abingtest,然后到webapps目录下搜索到该项目文件夹。

    b) 项目文件找到后,开始寻找类文件。

    这个时候Tomcat去Web.xml文件中寻找<servlet-mapping> 配置节中包含”servlet/FirstServlet”字符串,进而找到该类文件所在的位置。

    3. Servelt中的doGet() 和 doPost() 方法

    我们写的FirstServlet 继承了HttpServlet ,重写了HttpServlet中的doGet() 方法,HttpServlet中还有一个doPost()方法。这两个方法都是用来处理Http请求的。Servlet会根据我们提交表单的方法(method=post/get)调用service方法来自动选择(我们在下一篇文章中来详细说明一下Service方法是如何自动调用FirstServlet中的doGet()方法的)

    4. Servlet如何接收数据

    import javax.servlet.http.*;

    import javax.servlet.*;

    import java.io.*;

    public class FirstServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    throws ServletException, java.io.IOException {

    //获取表单数据

    String userName = request.getParameter(“userName”);

    }

    }

    Http协议会将网页中的所有内容包装成为一个request对象传递给servlet ,Servlet通过这个对象拿到表单中的所有数据,处理完成之后,通过Response对象返回给客户端浏览器。

    5. Servlet的生命周期

    Servlet的生命周期是由Tomcat容器管理的

    a) 客户发出请求—>Web 服务器转发到Web容器Tomcat;

    b) Tomcat主线程对转发来用户的请求做出响应创建两个对象:HttpServletRequest和HttpServletResponse;

    c) 从请求中的URL中找到正确Servlet,Tomcat为其创建或者分配一个线程,同时把2创建的两个对象传递给该线程;

    d) Tomcat调用Servlet的servic()方法,根据请求参数的不同调用doGet()或者doPost()方法;

    e) 假设是HTTP GET请求,doGet()方法生成静态页面,并组合到响应对象里;
    Servlet线程结束,Tomcat将响应对象转换为HTTP响应发回给客户,同时删除请求和响应对象。
    从该过程中,我们可以理解Servlet的生命周期:Servlet类加载(对应3步);Servlet实例化(对应3步);调用init方法(对应3步);调用service()方法(对应4、5步);;调用destroy()方法(对应6步)。

    五:Servlet生命周期的各个阶段

  • 相关阅读:
    innodb文件
    Innodb 存储引擎
    第二章 flex输入输出结构
    第二章 flex输入输出
    第二章 flex处理二义性
    第一章 flex单词计数程序
    Compile SQLite3 from individual files
    标 题: [心得]传统IT转互联网面试经验分享
    【设计模式】二:策略模式
    python 爬虫第三例--爬美女图片
  • 原文地址:https://www.cnblogs.com/wnlja/p/3912594.html
Copyright © 2011-2022 走看看