Servlet
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容。
Interface Servlet java实现的一个接口,看官方文档介绍:
- 所有的Servlets都必须实现该接口。通常可以直接继承GenericServlet或HttpServlet。
- 一个Servlet是一个运行在web服务器中的java程序,Serlvets接收和响应web客户端发出的Http请求。
- 该接口定义了Servlet的生命周期的方法。
- servlet构造,然后用init(ServletConfig config)初始化方法。
- 任何来自客户机的调用都是用service(ServletRequest req,ServletResponse res)方法处理。
- servlet被移除销毁的时候会调用destroy方法。
Web应用中怎么配置Servlet
1,创建一个类继承GenericServlet或HttpServlet类。
2,在WEB-INF目录下的web.xml文件中配置Servlet的映射
例如:
<!-- 配置一个Servlet类 -->
<servlet>
<servlet-name>dataSystem-dispatcher</servlet-name>
<servlet—class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<!-- 配置Servlet的映射 用来供外界访问 -->
<servlet-mapping>
<servlet-name>dataSystem-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Servlet的运行过程
-
Servlet程序是由Web服务器调用的,web服务器收到客户端的Servlet访问请求后:
第一步:Web服务器首先检查是否已经装载并创建了该Servlet的实例对象,如果是,则直接执行第4步,否则,执行第2步。
第二步:装载并创建该Servlet的一个实例对象。
第三步:调用Servlet实例对象的init()方法。
第四步:创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
第五步:Web应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
Servlet接口的实现类
- Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。
- HttpServlet只能够处理Http请求的Servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,比Servlet接口的功能更强大。因此我们在编写Servlet时,通常应该继承HttpServlet类。
- HttpServlet在实现Servlet接口时,复写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如果为POST请求,则调用doPost方法,因此,在编写Servlet时,通常只需要覆写doGet或doPost方法,无需覆写service方法。
Servlet的细节
Servlet细节1——Servlet配置:
-
由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把Servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
-
<servlet>元素用于注册Servlet,包含两个主要子元素:
<servlet> <!--给Servlet类注册一个名字--> <servlet-name>HelloServlet</servlet-name> <!--Servlet完整类名--> <servlet-class>main.HelloServlet</servlet-class> </servlet>
-
一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含两个子元素:
<servlet-mapping> <!--Servlet的注册名称--> <servlet-name>HelloServlet</servlet-name> <!--Servlet对外访问的路径--> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping>
Servlet细节2——Servlet映射多个URL及通配符的使用:
- 同一个Servlet可以被映射到多个URL上,即多个 <servlet-mapping>元素的 <servlet-name>名称相同,而元素<url-pattern>的值不同。
- 在Servlet映射到URL中也可以使用﹡通配符,但是只能有两种固定的格式:一种格式是“﹡.扩展名”,另一种格式是以正斜杠(/)开头并以“/﹡”结尾。
例如:
<servlet-mapping>
<servlet-name>任何名字</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>任何名字</servlet-name>
<url-pattern>/aciton/*</url-pattern>
</servlet-mapping>
星号在前的形式是优先级最低的:﹡.do
其他的优先级是URL地址和那个最像就是先调用那个。
注意:web应用的web.xml文件发生变化时不需要重启服务器,因为tomcat的conf目录下context.xml文件中有这么一句: <WatchedResource>WEB-INF/web.xml</WatchedResource>设置了监听web.xml文件。
Servl细节3——通配符示例:

Servlet细节4——servlet调度:
- Servlet是一个供其他java程序(Servlet引擎)调用的Java类,他不能独立运行,它的运行完全由Servlet引擎来控制和调度。
- 针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦被创建,它就会驻留在内存中,为后续的其他请求服务,直至web容器退出,Servlet实例对象才会销毁。
- 在Servlet的整个生命周期内,Servlet的init方法只会调用一次。而对一个Servlet的每次访问请求都会导致Servlet引擎调用一次Servlet的service方法。对于每次访问请求,Servlet引擎都会创建新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给service方法,service方法再根据请求方式分别调用doXXX方法。
Servlet细节5——< load-on-startup >元素:
-
如果在<servlet>元素中配置了一个<load-on-startup>元素,那么web应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法初始化。
例如:
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>main.HelloServlet</servlet-class> <!--配置了该属性,该Servlet会随着应用的启动而被创建和初始化。中间的数字必须是整数,代表优先级,数字越小越早启动--> <load-on-startup>2</load-on-startup> </servlet>
-
<load-on-startup>元素用途:为web应用写一个initServlet,这个Servlet配置为启动时装载,为这个web应用创建必要的数据库表和数据。
Servlet细节6——缺省Servlet:
- 如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前web应用程序的缺省Servlet。
- 凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。
- 在<tomcat的安装目录>\conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。
- 当访问tomcat服务器的某个静态HTML文件和图片时,实际上是在访问这个缺省的Servlet。
Servlet细节7——线程安全问题:
- 当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源,就有可能引发线程安全问题。
- 如果某个Servlet实现了SingleThreadModel接口,那么servlet引擎将以单线程模式来掉用其service方法。
- 对于实现了SingleThreadModel接口的servlet,Servlet引擎仍然支持对该servlet的多线程并发访问,其采用的方式是产生多个servlet实例对象,并发的每一个线程分别调用一个独立的servlet对象。
- 实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在servletAPI 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。
- 所以要解决servlet的线程安全问题还是要用传统的synchronization。
*学习servlet技术,把servlet自身搞清楚后,再把web服务器在调用servlet的时候传输的对象Request、Response、ServletConfig、ServletContext、Session、Cookie学明白,那么servlet技术就算学明白了。
网友评论