Servlet

  • Servlet技术体系
    • Servlet

①Servlet接口

②GenericServlet抽象类

  • 对Servlet功能进行了封装和完善,将service(ServletRequest req, ServletResponse res)保留为抽象方法,让使用者仅关心业务实现即可。

③HttpServlet抽象类

  • 对GenericServlet进行了进一步的封装和扩展,更贴近HTTP协议下的应用程序编写,在service(ServletRequest req, ServletResponse res)方法中,根据不同HTTP请求类型调用专门的方法进行处理。
  • 今后在实际使用中继承HttpServlet抽象类创建自己的Servlet实现类即可。重写doGet(HttpServletRequest req, HttpServletResponse resp)和doPost(HttpServletRequest req, HttpServletResponse resp)方法实现请求处理,不再需要重写service(ServletRequest req, ServletResponse res)方法了。

  • ServletConfig接口:封装了Servlet配置信息
  • ServletContext接口:封装了当前Web应用上下文信息
  • HttpServletRequest接口:封装了HTTP请求信息,ServletRequest的子接口
  • HttpServletResponse接口:封装了HTTP响应信息,ServletResponse的子接口
  • Servlet生命周期
    • 应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为——这就是对象的生命周期。
    • Servlet对象是Servlet容器创建的,生命周期方法都是由容器调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。
    • Servlet生命周期的主要过程

①Servlet对象的创建

默认情况下,Servlet容器第一次收到HTTP请求时创建对应Servlet对象。容器之所以能做到这一点是由于我们在注册Servlet时提供了全类名,容器使用反射技术创建了Servlet的对象。

②Servlet对象初始化

  • Servlet容器创建Servlet对象之后,会调用init(ServletConfig config)方法,对其进行初始化。在javax.servlet.Servlet接口中,public void init(ServletConfig config)方法要求容器将ServletConfig的实例对象传入,这也是我们获取ServletConfig的实例对象的根本方法。

[参考阅读]

●这是依赖注入思想的一种实现,所谓依赖注入指的是程序中需要的对象不是由开发人员自己创建或获取,而是由“环境”——也就是容器主动“注入”到我们的程序中。这样做的好处是屏蔽复杂对象的创建细节或简化开发过程。这一思想在很多框架中都得到了体现,特别是Spring的IOC容器就是依赖注入思想的典型实现。

  • 为了简化开发,GenericServlet抽象类中实现了init(ServletConfig config)方法,将init(ServletConfig config)方法获取到的ServletConfig对象赋值给了成员变量ServletConfig config,目的是使其它方法可以共享这个对象。这时有一个问题:如果子类重写了这个init(ServletConfig config)方法,有可能会导致成员变量config对象赋值失败。所以GenericServlet抽象类另外提供了一个无参的public void init()方法,并在init(ServletConfig config)方法中调用,作为子类进行初始化操作时重写使用。而这个无参的init()方法之所以没有设计成抽象方法,是为了避免子类继承时强制实现这个方法带来的麻烦,使用者可以根据需要选择是否要覆盖这个方法。

③处理请求

  • 在javax.servlet.Servlet接口中,定义了service(ServletRequest req, ServletResponse res)方法处理HTTP请求,同时要求容器将ServletRequest对象和ServletResponse对象传入。
  • 在HttpServlet抽象类中,service(ServletRequest req, ServletResponse res)方法将ServletRequest对象和ServletResponse对象强转为了HttpServletRequest、HttpServletResponse子类对象,这样更适合于HTTP请求的处理,所以在doGet()和doPost()方法中使用的就是HttpServletRequest、HttpServletResponse的实现类对象了。

④Servlet对象销毁

  • Web应用卸载或服务器停止执行时会销毁Servlet对象,而销毁之前为了执行一些诸如释放缓存、关闭连接、保存数据等操作,所以设计了public void destroy()方法。
  • ServletConfig接口

  • ServletConfig接口封装了Servlet配置信息,这一点从接口的名称上就能够看出来。但同时,代表当前Web应用的ServletContext对象也封装到了ServletConfig对象中,使ServletConfig对象成为了获取ServletContext对象的一座桥梁。
  • ServletConfig对象的主要功能

①获取Servlet友好名称

②获取Servlet初始化参数

③获取ServletContext对象

  • ServletContext接口

  • Web容器在启动时,它会为每个Web应用程序都创建一个对应的ServletContext对象,它代表当前Web应用——作用很像餐厅的经理。
  • 由于一个Web应用程序中的所有Servlet都共享同一个ServletContext对象,所以ServletContext对象也被称为 application 对象(Web应用程序对象)。
  • 在应用程序中能够获取运行环境或容器信息的对象通常称之为“上下文对象”。
  • ServletContext对象的主要功能

①获取WEB应用程序的初始化参数

  • 设置Web应用初始化参数的方式是在web.xml的根标签下加入如下代码

<!-- Web应用初始化参数 -->

<context-param>

<param-name>ParamName</param-name>

<param-value>ParamValue</param-value>

</context-param>

  • 获取Web应用初始化参数

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//1.获取ServletContext对象

ServletContext context = this.getServletContext();

//2.获取Web应用初始化参数

String paramValue = context.getInitParameter("ParamName");

System.out.println("paramValue="+paramValue);

}

 

②获取虚拟路径所映射的本地路径

  • 虚拟路径:浏览器访问Web应用中资源时所使用的路径。
  • 本地路径:资源在文件系统中的实际保存路径。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//1.获取ServletContext对象

ServletContext context = this.getServletContext();

//2.获取index.html的本地路径

//index.html的虚拟路径是“/index.html”,其中“/”表示当前Web应用的根目录,

//即WebContent目录

String realPath = context.getRealPath("/index.html");

//realPath=D:\DevWorkSpace\MyWorkSpace\.metadata\.plugins\

//org.eclipse.wst.server.core\tmp0\wtpwebapps\MyServlet\index.html

System.out.println("realPath="+realPath);

}

 

③application域范围的属性

  • ServletContext对象与当前Web应用一致,即Web应用加载时创建,Web应用卸载时销毁。