欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Servlet学习补充

程序员文章站 2022-10-17 14:46:14
Servlet学习补充 ......

Servlet学习补充

=============================================================================
Servlet是sun公司提供的一门用于开发动态web资源的技术。
    Sun公司在其API中提供了一个servlet接口,用户若想开发一个动态web资源(即开发一个Java程序向浏览器输出数据),
    需要完成以下2个步骤:
        1. 编写一个Java类,实现servlet接口。
        2. 把开发好的Java类部署到web服务器中。
        
    提示:按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet。
-----------------------------------------------------------------------------
Servlet的运行过程
    Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
    1. Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4步,否则,执行第2步。
    2. 装载并创建该Servlet的一个实例对象。 
    3. 调用Servlet实例对象的init()方法。
    4. 创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个用于封装HTTP响应消息的HttpServletResponse对象,
       然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
    5. WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
-----------------------------------------------------------------------------
Servlet的生命周期(1)
    1. Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。
    2. 针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象(单实例),
       也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。
    3. 在Servlet的整个生命周期内,Servlet的init方法只被调用一次。
       而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。
       对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,
       然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXxx方法。 
Servlet的生命周期(2)
    如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。
    举例:
    <servlet>
        <servlet-name>servletDemo1</servlet-name>
        <servlet-class>com.itheima.servlet.ServletDemo1</servlet-class>
        <!-- 设置启动时就加载,数值越小越先启动 (但不建议写0) -->
        <load-on-startup>2</load-on-startup>
    </servlet>
    用途:为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。
    
    从提高Servlet容器运行性能的角度出发,Servlet规范为Servlet规定了不同的初始化情形。
    如果有些Servlet专门负责在web应用启动阶段为web应用完成一些初始化操作,则可以让它们在web应用启动时就被初始化。
    对于大多数Servlet,只需当客户端首次请求访问时才被初始化。
    假设所有的Servlet都在web应用启动时被初始化,那么会大大增加Servlet容器启动web应用的负担,
    而且Servlet容器有可能加载一些永远不会被客户访问的Servlet,白白浪费容器的资源。
-----------------------------------------------------------------------------
Servlet接口实现类
    Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
    HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。
    因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。

    HttpServlet在实现Servlet接口时,重写了service方法,该方法体内的代码会自动判断用户的请求方式,
    如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用HttpServlet的doPost方法。
    因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
    
    注:doGet和doPost方法里面的形参分别是HttpServletRequest、HttpServletResponse。
-----------------------------------------------------------------------------
Servlet的线程安全
    当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,
    并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
    
    如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。
    SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。 
    
    对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,
    其采用的方式是产生多个Servlet实例对象(资源浪费大),并发的每个线程分别调用一个独立的Servlet实例对象。
    
    实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,
    而真正意义上解决多线程安全问题是指:一个Servlet实例对象被多个线程同时调用的问题。
    事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。 
-----------------------------------------------------------------------------
资源文件通常有两种方式:

    对于简单的资源文件,即包含key=value的形式,我们一般采用properties,这些文件的扩展名一般为*.properties。
    对于较复杂的资源文件,采用XML格式。
    
通常资源文件放在src目录或者WEB-INF目录下。

在web工程中,要获得某个文件的路径,我们一般都采取相对于web工程"/"的相对路径。

在src下放置的db.properites配置文件,
    法一:利用Servletcontext.getResourceAsStream("/WEB-INF/classes/db.properties"); 来获取。
    法二:利用ServeltContext.getRealPath("/WEB-INF/classes/db.properties"); 来获取。

web project工程目录结构图:
  Servlet学习补充 =============================================================================