tomcat是一个优秀的java web应用容器,帮助我们管理着servlet(可以理解服务器端处理数据的java小程序)等,使我们只需要将重心专注于业务逻辑。说白了就是管理我们的程序的容器,处理加载、实例化、垃圾回收等等一系列和业务无关的操作。
什么是web容器?
servlet没有main方法,那我们如何启动一个servlet,如何结束一个servlet,如何寻找一个servlet等等,都受控于另一个java应用,这个应用我们就称之为web容器。
我们最常见的tomcat就是这样一个容器。如果web服务器应用得到一个指向某个servlet的请求,此时服务器不是把servlet交给servlet本身,而是交给部署该servlet的容器。要有容器向servlet提供http请求和响应,而且要由容器调用servlet的方法,如doPost或者doGet。
web容器的作用
服务器,硬件角度上说就是一台高性能的Computer。我们通常指的服务器其实应该是装有能够处理具体请求事务的服务器软件的Computer。比如最常见的www服务器、mail服务器、计费服务器、ftp服务器等等。很多时候人们常把诸如Tomcat、IIS、Weblogic 也称之为web服务器,其实这些只是用于开发、集成、部署和管理Web应用、网络应用和数据库应用的应用服务器软件。
1、什么是容器?
Servlet没有main()方法。Servlet受控于另一个Java应用,这个Java应用称为容器。Tomcat就是这样一个容器。如果web服务器应用得到一个指向servlet的请求(而不是其他请求,如请求一个普通的静态HTML),此时服务器不是把这个请求交给servlet本身,而是交给部署该servlet的容器,要由容器调用servlet的方法,如doPost()或doGet()。
2、容器能提供什么?
通信支持:利用容器提供的方法,你能轻松地让servle与Web服务器对话;
生命周期管理:容器控制着servlet的生与死。它会负责加载类、实例和初始化servlet、调用servlet方法,并使servlet实例能够被垃圾回收。
多线程支持:容器会自动地为它接收的每个servlet请求创建一个新的java线程。针对客户机的请求,如果servlet已经运行完相应的HTTP服务方法,这个线程就会结束(也就是会死掉)。
声明方式实现安全:利用容器,可以使用XML部署描述文件配置(和修改)安全性,而不必将其硬编码写到servlet(或其他)类代码中。
JSP支持:负责把JSP代码翻译成真正的java。
web应用程序需要部署到web容器中才能运行,两者都必须符合javaEE规范。web容器的应用程序规范如下:
1.目录结构规范:javaWeb程序的所有文件都包含在一个文件夹中,包含WEB-INF子文件夹和META-INF子文件夹,WEB-INF文件夹包含classes文件夹和lib文件夹以及web.xml。
容器如何处理请求
How the Container handles a request01.PNG
client点击一个URL,其URL指向一个servlet而不是静态界面。
How the Container handles a request02.PNG
容器识别出这个请求索要的是一个servlet,所以创建两个对象:
- httpservletrequest
- httpservletresponse
容器根据请求中的URL找到对应的servlet,为这个请求创建或分配一个线程,并把两个对象request和response传递到servlet线程中。
Paste_Image.png
容器调用servlet的service()方法。根据请求的不同类型,service()方法会调用doGet()或者doPost()方法。
Paste_Image.png
doGet()方法生成动态页面,然后把这个页面填入到response对象中,此时,容器仍然拥有response对象的引用。
Paste_Image.png
线程结束。容器把response对象转换成http响应,传回client,并销毁response和request对象。
URL与servlet映射模式
<servlet>
<servlet-name>Ch1Servlet</servlet-name>
<servlet-class>ch1Servlet.Ch1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Ch1Servlet</servlet-name>
<url-pattern>/Ch1Servlet</url-pattern>
</servlet-mapping>
servlet有三个名字:
- 客户知道的URL名
<url-pattern>/Ch1Servlet</url-pattern>
- 部署人员知道的秘密的内部名
<servlet-name>Ch1Servlet</servlet-name>
- 实际文件名
<servlet-class>ch1Servlet.Ch1Servlet</servlet-class>
Servlet与普通Java的区别:
servlet是一个供其他java程序调用的java类。他不能独立运行,她的运行完全由servlet引擎控制和调度
针对客户端的多次servlet请求,通常情况下,服务器只会创建一servlet实例对象,也就是说servlet一旦创建,他就会驻留在内存之中,为后续的其他请求服务,直至web容器推出,servlet实力对象才会被销毁。
在servlet的整个生命周期内,servlet的init方法只会被调用一次,而对一个Servlet的每次访问都导致引擎调用一次servlet的service方法。对于每次访问请求,servlet引擎都会创建有哥httpservletRequest请求对象和一个httpservletReponse响应对象,然后将这两个对象作为参数传递给servlet的service()方法。servlet方法再根据请求方式分别调用doXXX方法。
servlet的线程安全问题
当多个客户端兵法访问一个servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程调用servlet的service方法,因此service方法内如果放同一个资源的话,就有可能引发线程安全问题,
针对servlet线程安全问题,Sun公司是提供有解决方案的:让Servlet去实现一个SingleThreadModel接口,如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以但线程模式来调用期Service方法
查看Sevlet的API可以看到,SingleThreadModel接口中没有定义任何方法和常量,在Java中,把没有定义任何方法和常量的接口称之为标记接口,经常看到的一个最典型的标记接口就是"Serializable",这个接口也是没有定义任何方法和常量的,标记接口在Java中有什么用呢?主要作用就是给某个对象打上一个标志,告诉JVM,这个对象可以做什么,比如实现了"Serializable"接口的类的对象就可以被序列化,还有一个"Cloneable"接口,这个也是一个标记接口,在默认情况下,Java中的对象是不允许被克隆的,就像现实生活中的人一样,不允许克隆,但是只要实现了"Cloneable"接口,那么对象就可以被克隆了。
让Servlet实现了SingleThreadModel接口,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。
对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。
实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。
servlet:
init()和destroy()方法只会被调用一次,service()方法会被多次调用,只要有请求service()方法就会被调用。
Request作为域对象作用范围
Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。一次请求范围:从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。
- ServletContext对象之获取web项目信息
- 什么是ServletContext?
- ServletContext对象有什么作用?
- ServletContext对象又称为Servlet的上下文对象,保存了整个web项目的信息,通过这个上下文对象可以保存或者获取web项目的信息。
一个web项目只有一个ServletContext对象,服务器会为每个项目创建一个ServletContext对象。
- ServletContext对象之读取web项目下文件
- 如何获取web项目下的文件资源?
想要获取web项目下的文件资源,使用传统的IO流方式是不行的,因为传统的IO流采用的是相对jre环境,而我们的web项目最终要发布到Tomcat服务器上,环境不一样。所以要使用ServletContext对象来获取,ServletContext身上有三个跟路径相关的方法:
- ServletContext对象之作为域对象存取数据
- 什么是域对象?
- ServletContext如何进行存值、取值和移除值?
- 如果把一个数据存到某个对象身上,在多个地方又能通过这个对象取出来,那么这个对象存的值就有了一定的作用范围,这个对象也就称为域对象。ServletContext作为一个域对象,它的作用范围是整个web项目,因为服务器会为每个web项目创建一个ServletContext对象,只要这个web项目在服务器上没被移除或者服务器没有关闭,那么ServletContext域对象就存在,它身上的数据也就在。