标签:java web servlet servlet生命周期
Servlet是JavaWeb的核心,JSP以及其他优秀的web框架都是基于Servlet实现的。
Servlet是用Java编写的与平台无关的服务端组件,是基于请求-响应模式工作的,运行在Servlet容器(反射机制)中,其生命周期由Servlet容器管理。Servlet实例通常用做控制器,根据不同的请求,经过处理后,将处理结果返回到客户端或转发给其他Servlet组件。
Servlet 容器,是web服务器或应用服务器的组成部分,同时也负责管理Servlet实例的生命周期。Servlet容器也可以为Servlet实例提供其他的服务,比如资源服务、安全服务、线程服务等。Servlet容器可以集成到web服务器或应用服务器中,也可以作为独立的程序嵌入到web服务器或应用服务器中。
i. 客户端向web服务器发起一个HTTP请求;
ii. HTTP请求被web服务器接受,并移交给Servlet引擎;
iii. Servlet引擎根据Servlet的配置来确定加载的Servlet,并调用init方法进行初始化,并把request对象、response对象传给Servlet实例。
iv. Servlet实例初始化后,通过service方法处理客户端请求,通过request对象获取客户的请求信息以及其他的信息。servlet处理完请求后把要返回的信息放入response对象返回到客户端。
v. 一旦Servlet实例完成了请求的处理,Servlet引擎就会刷新response,把控制权返回给web服务器。
vi. 当Servlet实例从Servlet容器中移除时,会调用destroy()方法,如reload应用、重新启动服务器等。
n Servlet不可以独立运行
Servlet实例必须运行在Servlet容器中,由容器来调用它的生命周期方法。
n Servlet不是一个线程
当服务器接收到客户端的请求时,它会在一个单独的线程中来执行Servlet实例的方法。
n Servlet线程安全问题
当Servlet被第一次访问后,就被加载到Servlet容器,以后该实例会对各个请求服务,这就涉及到线程安全问题(Servlet并不是线程安全的),如售票系统等,这时需要同步机制处理关键操作。原则如下:
a) 当一个变量需要多个用户共享,则应当在访问该变量的时候,加上同步机制;
b) 当一个变量不需要共享,则直接在Servlet实例的doGet方法或doPost方法中定义,这样就不会存在线程安全问题,因为每一次访问,doGet或doPost方法都会被调用,方法中的变量会被重新创建。
Tomcat并不仅仅是一个Servlet容器,它同时具有管理html以及其他资源的功能。Tomcat的体系结构如下图所示:
Tomcat的容器分为四个等级,如下
1) Server代表整个web服务器,单例的;
2) Service是一个或多个Connector,以及一个Engine的集合,ngine负责处理所有Connector的客户请求;
3) Connector在指定的端口上监听客户端的请求,并将获得的请求交给Engine来处理,从Engine获取响应并返回给客户端;
4) Engine是多个虚拟主机的集合,每个虚拟主机都有一个域名;当Engine获得一个请求时,会将请求对应到匹配的Host上,然后把该请求交给匹配的Host来处理;
5) Host:虚拟主机,每个虚拟主机下可以部署多个web应用,每个web应用对应一个Context。当Host获取一个请求时,会将该请求交给对应匹配的Context;
6) Context:一个Context对应一个Web应用,包含一个或多个Servlet。当Context启动时,将首先加载Tomcat的web.xml部署的Servlet;之后加载web应用配置文件web.xml中的被生声明为启动加载的Servlet。最后,当Context收到请求时,将根据Web应用的web.xml文件加载匹配的Servlet(若已加载,则忽略)。
综上所属,Tomcat处理HTTP请求的流程如下(假设客户端的请求为localhost:8080/jw/index.jsp):
i. 请求被发送到本机端口8080,被在那里监听的Connector获取请求;
ii. Connector把监听到的请求交给其所在的Engine来处理,并等待Engine的响应;
iii. Engine获得请求localhost/js/index.jsp,匹配到默认主机localhost,将请求/jw/index.jsp交给localhost主机;
iv. localhost主机获取/jw/index.jsp,匹配到web应用jw,则请求交给web应用jw;
v. web应用jw获取请求/index.jsp,找到对应index.jsp的Servlet,加载对应的Servlet至Servlet容器,之后调用Servlet实例的service方法进行处理,处理完毕后,将处理结果封装为HttpResponse实例返回给localhost主机;
vi. localhost主机将结果放回给Engine;
vii. Engine将处理结果返回给Connector;
viii. Connector将处理结果返回给客户端。
当开发好Servlet后,需要部署Servlet,才能被服务器加载。部署Servlet时,需要在项目的web.xml添加配置信息,如下
<servlet>
<servlet-name>index</servlet-name>
<!--servlet-name要与servlet-mapping中的name一致-->
<servlet-class>org.ssl.web.servlet.IndexServlet</servlet-class>
<!--servlet-class 就是完整的类名=包名+类名,但不能跟.java-->
</servlet>
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern>/</url-pattern>
<!--url-pattern 指明了资源名,格式为/+资源名,不可忘记/-->
</servlet-mapping>
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
一个Servlet可以对应多个servlet-mapping,即可以映射多个url;url可以采用通配符的形式。如果一个Servlet在应用启动时,就需要被加载可以配置<load-on-startup>子标签,若有多个Servlet在应用启动时被加载,<load-on-startup>子标签的数值表示该Servlet被加载的顺序。
在web.xml配置servlet时,我们可以为其配置一些参数信息,以便在Servlet中获取这些参数,如下
<servlet>
<description></description>
<display-name>Test</display-name>
<servlet-name>Test</servlet-name>
<servlet-class>Test</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>ssl</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/Test</url-pattern>
</servlet-mapping>
在Servlet中,这些参数可以通过ServletConfig对象获取,如下
private ServletConfig servletConfig;
@Override
public void init(ServletConfig config) throws ServletException
{
super.init(config);
this.servletConfig=config;
String value=config.getInitParameter("nam");
}
此外还可以通过<context-param>标签设置参数,称为上下文配置参数,这些参数可以被所有的Servlet读取,如下
<context-param>
<param-name>name</param-name>
<param-value>ssl</param-value>
</context-param>
可以在Servlet中通过ServletContext实例获取这些参数。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:java web servlet servlet生命周期
原文地址:http://blog.csdn.net/sunshuolei/article/details/48089979