Java Web基础回顾 —Servlet

Servlet运行在多线程的服务器上,要注意Servlet要处理并发的请求,需要小心对共享资源的同步访问,共享资源包括实例或者类变量,以及外部的对象比如文件,数据库连接,网络连接。

  1. HttpServlet源码分析:
    1)每个Servlet都不需要事先Servlet接口,GenericServlet是通用的、不特定于任何协议的Servlet,它实现了Servlet接口;HttpServlet继承了GenericServlet,因此开发只需继承HttpServlet父类即可。
    2)Servlet接口中定义了service(ServletRequest, ServletRespionse) 方法,HttpServlet对该方法进行实现,就是将ServletRequest与ServletResponse强制类型转换为HttpServletRequest与HttpServletResponse,并调用自己定义的service(HttpServletRequest, HttpServletResponse)方法,该方法首先获得请求的方法名,如果是GET,则会调用doGet方法,其他依次类推。注意 HttpServlet类中定义的doGet以及doPost方法都是返回错误信息,所以就强制我们定义自己的Servlet时候override这些方法。
  2. Servlet 生命周期详解:
    • Servlet的核心就是javax.servlet.Servlet接口,定义了五个方法,其中三个代表了Servlet的生命周期:
      • init方法:负责初始化Servlet对象;
      • service方法:负责响应客户的请求;
      • destroy方法:当Servlet对象退出生命周期时,负责释放占用的资源。
      • ServletRequest接口
        该接口封装了客户请求信息,如客户请求方式、参数名和参数值、客户端正在使用的协议,以及发出客户请求的远程主机信息等。同时提供ServletInputStream以二进制形式来读取客户请求数据流。
        其子类可以为Servlet提供更多的和特定协议相关的数据,如HttpServletRequest提供了读取HTTP Head信息的方法。
    • ServletResponse接口
      该接口为Servlet提供了返回响应结果的方法。允许Servlet设置返回数据的长度和MIME类型,并提供输出流ServletOutputStream。
      ServletResponse的子类可以提供更多和特定协议相关的方法,如HttpServletResponse提供设定HTTP HEAD信息的方法。
    • Servlet的初始化阶段:
      下面时刻会装载Servlet
      • Servlet容器启动时自动装载某些Servlet(web.xml Servlet配置里添加load-on-start 参数)
      • Servlet容器启动之后,客户端首次向Servlet发出请求
      • Servlet的类文件被更新后,重新装载Servlet
        Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化, 在Servlet的整个生命周期中,init方法只会被调用一次。
    • 请求响应阶段
      对于到达Servlet容器的客户请求,Servlet容器创建ServletRequest和ServletResponse对象,然后调用Servlet的service() 方法。service方法从ServletRequest对象获得客户请求信息、处理该请求,并通过ServletResponse对象向客户返回响应结果。
      对于Tomcat 7来说,客户传递过来的参数放在一个LinkedHashMap里面:
      private final Map<String,ArrayList> paramHashValues =
      new LinkedHashMap<String,ArrayList>();是一个String —> ArrayList的键值映射。
    • 请求终止阶段
      当Web应用被终止,或Servlet容器终止运行,或Servlet容器重新装载Servlet的新实例时,Servlet容器会调用Servlet的destroy方法。在destroy方法中,可以释放Servlet所占用的资源。
    • Servlet对象的创建
      默认情况下,当Web客户第一次请求访问某个Servlet时,Web容器创建这个Servlet实例。
      但是如果设置了子元素,容器在启动Web应用时,将按照指定的顺序创建并初始化这个Servlet。(某些Servlet的配置没有配置元素,这样我们就无法通过url地址方式访问这个Servlet,这种Servlet通常会在元素中配置一个,让容器在启动的时候自动加载该Servlet,并且调用其init方法完成一些全局性的初始化工作)。
    • ServletContext和Web应用关系
      当Servlet容器启动Web应用时,并为每个Web应用创建唯一ServletContext对象(JSP内置对象里application的类型),可以把ServletContext看成是一个Web应用的服务器端组件的共享内存。
    • Servlet多线程问题
      Servlet/JSP默认是以多线程模式执行,所以在编写代码时需要非常细致的考虑多线程同步问题。
      Servlet同时也是单实例的。所以Servlet实例中的成员变量会造成多线程问题。解决方案:去除实例变量,使用局部变量。
原文地址:https://www.cnblogs.com/nextStep/p/6694681.html