Servlet运行在多线程的服务器上,要注意Servlet要处理并发的请求,需要小心对共享资源的同步访问,共享资源包括实例或者类变量,以及外部的对象比如文件,数据库连接,网络连接。
- 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这些方法。 - 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实例中的成员变量会造成多线程问题。解决方案:去除实例变量,使用局部变量。
- Servlet的核心就是javax.servlet.Servlet接口,定义了五个方法,其中三个代表了Servlet的生命周期: