Servlet的生命周期及工作原理

Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。

 

jsp九大内置对象

1.request对象:

客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。

2.response对象:

response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。

3.session对象:

session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.

4.out对象:

out对象是JspWriter类的实例,是向客户端输出内容常用的对象

5.page对象:

page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例

6.application对象:

application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。

7.exception对象:

exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象

8.pageContext对象:

    pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。

9.config对象:

   config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)

 

ServletConfig对象(servlet所需要的初始化参数封装在ServletConfig对象中):

     1>获得字符集编码

       2>.获得连接数据库的信息

    3>.获得配置信息

ServletContext对象(WEB容器启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,代表当前应用):

     1>.多个WEB组件间使用它实现数据共享

  ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。

在serlvet中,可以使用如下语句来设置数据共享

  ServletContext context = this.getServletContext();  //servletContext域对象

  context.setAttribute("data", "共享数据"); //向域中存了一个data属性

在另一个servlet中,可以使用如下语句来获取域中的data属性

  ServletContext context = this.getServletContext();

  String value = (String) context.getAttribute("data");  //获取域中的data属性

  System.out.println(value);

     2>.通过ServletContext对象获取整个WEB应用的配置信息

  String url = this.getServletContext().getInitParameter("url");

  String username = this.getServletContext().getInitParameter("username");

  String password = this.getServletContext().getInitParameter("password");

     3>.通过ServletContext对象实现servlet转发------

由于servlet中的java数据不易设置样式,所以serlvet可以将java数据转发到JSP页面中进行处理

  this.getServletContext().setAttribute("data","serlvet数据转发");

  RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/viewdata.jsp");

  rd.forward(request, response);

   4>.通过servletContext对象读取资源文件

        在实际开发中,用作资源文件的文件类型,通常是:xml、properties,而读取xml文件必然要进行xml文档的解析,所以以下例子只对properties文件进   行读取(在一个web工程中,只要涉及到写地址,建议最好以/开头)

  在web工程中,我们一般来说,是不能采用传统方式读取配置文件的,因为相对的是jvm的启动目录(tomcat的bin目录),所以我们要使用web绝对目录来获取配置文件的地址

  读取资源文件的三种方式:

  第一种:使用ServletContext的getResourceAsStream方法:返回资源文件的读取字节流

  InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

  Properties prop = new Properties(); 

  prop.load(in);

  String url = prop.getProperty("url");

  第二种:使用ServletContext的getRealPath方法,获得文件的完整绝对路径path,再使用字节流读取path下的文件

  String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");

  String filename = path.substring(path.lastIndexOf("\\")+1);

  //相比第一种方法的好处是:除了可以获取数据,还可以获取资源文件的名称

  FileInputStream in = new FileInputStream(path);

  Properties prop = new Properties();

  prop.load(in);

  String url = prop.getProperty("url");

  第三种:使用ServletContext的getResource方法,获得一个url对象,调用该类的openStream方法返回一个字节流,读取数据

  URL url = this.getServletContext().getResource("/WEB-INF/classes/db.properties");

  InputStream in = url.openStream();

  Properties prop = new Properties();

  prop.load(in);

  String url1 = prop.getProperty("url");

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。

public void service(ServletRequest req,ServletResponse res)

  throws ServletException,IOException

{

      HttpRequest request;

      HttpResponse response;

     try

     {

         req = (HttpRequest)request;

         res = (HttpResponse)response;

      }catch(ClassCastException e)

      {

         throw new ServletException("non-HTTP request response");

      }

      service(request,response);

}

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

protected void doGet(HttpServletRequest res,HttpServletResponse resp)

  throws ServletException,IOException

{

   String protocol = req.getProtocol();

   String msg = IStrings.getString("http.method_get_not_supported");

   if(protocol.equals("1.1"))

   {

      resp.sendError(HttpServletResponse.SC.METHOD.NOT.ALLOWED,msg);

    }

   esle

    {

      resp.sendError(HttpServletResponse.SC_BAD_REQUEST,msg);

    }

}

所以需要我们在自定义的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何时被创建:

  1,默认情况下,当WEB客户第一次请求访问某个Servlet的时候,WEB容器将创建这个Servlet的实例。

  2,当web.xml文件中如果<servlet>元素中指定了<load-on-startup>子元素时,Servlet容器在启动web服务器时,将按照顺序创建并初始化Servlet对象。

  注意:在web.xml文件中,某些Servlet只有<serlvet>元素,没有<servlet-mapping>元素,这样我们无法通过url的方式访问这些Servlet,这种Servlet通常会在<servlet>元素中配置一个<load-on-startup>子元素,让容器在启动的时候自动加载这些Servlet并调用init()方法,完成一些全局性的初始化工作。

Web应用何时被启动:

  1,当Servlet容器启动的时候,所有的Web应用都会被启动

  2,控制器启动web应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值