JavaWeb:Servlet知识点总结

来源:互联网 发布:pp助手无法安装软件 编辑:程序博客网 时间:2024/05/19 12:37

核心:Servlet,ServletConfig,ServletContext


浏览器与服务器通信的过程

客户端发送请求,由于要使用某种传输协议,所以在服务器这端,会有对应的连接器负责连接;Engine引擎分析处理传过来的url地址,截取出资源地址,去匹配配置文件中的<url-partern>找到对应的servlet对象以及对应的资源文件,然后发回给浏览器。

Servlet 执行以下主要任务:
1)读取浏览器发送的显式的数据。这包括网页上的 HTML 表单,或自定义的 HTTP 客户端程序的表单。(请求正文) 
2)读取浏览器发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。(请求头,请求行) 
3)处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。 
4)发送显式的数据(即文档)到浏览器。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。(响应正文) 

5)发送隐式的 HTTP 响应到浏览器。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他的任务。 (状态行和响应正文)


Servlet 生命周期

从创建直到毁灭的整个过程。
Servlet 遵循的过程:
1)Servlet 通过调用 init () 方法进行初始化。 
2)Servlet 调用 service() 方法来处理客户端的请求。 
3)Servlet 通过调用 destroy() 方法终止(结束)。 最后Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。


1)init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

2)service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost等方法。
service() 方法由容器调用,所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重载 doGet() 或 doPost() 即可。
3)doGet() 方法:GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。
4)doPost() 方法:POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。(只有HttpServlet中才有doPost(),doGet())
5)destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。


Servlet在web应用中的位置:

Html,jsp一般存在web应用根目录下,根目录下的文件外界可以直接访问。
java类、jar包、web应用的配置文件存在这个目录下,该目录下的文件外界无法非法直接访问,由web服务器负责调用。

Servlet执行过程:
1,客户端发出请求http://localhost:8080/Demo1/abc
2,根据web.xml文件的配置,找到<url-pattern>子元素的值“/hello”的<servlet-mapping>元素
3,读取<servlet-mapping>元素的<servlet-name>子元素的值,由此确定Servlet的名字为”HelloServlet”
4,找到<servlet-name>值为HelloServlet的<servlet>元素
5,读取<servlet>元素的<servlet-class>子元素的值,由此确定Servlet的类名为cn.itcast.HelloServlet。
6,Servlet,到Tomcat安装目录
/webapps/Demo1/WEB-INF/classes/cn/itcast目录下查找到HelloServlet.class文件。

Servlet的运行过程:
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
1)Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
2)装载并创建该Servlet的一个实例对象。 
3)调用Servlet实例对象的init()方法。
4)创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
5)WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。 


Servlet主要作用是:处理从客户端发送的请求及服务端的响应。

常见的属性<Servlet-mapping> <Servlet> <Servlet-class> <Servlet-name> <init-param>

Servlet标签用来定义一个Servlet对象

Servlet-mapping标签用来定义一个映射关系,其实就是访问方式

一个web项目中可以有多个servlet对象,每个Servlet对象实现不同的功能,对应不同的网页,就如同java应用程序中的一个项目有多个类;

web浏览器是通过url访问服务器资源
服务器直接调用servlet对象(servlet应用程序)。Servlet是运行于在web服务器(Tomcat)上的程序.它是作为来自web浏览器或其他客户端的请求和web服务器上的数据库或应用程序之间的中间层。


服务器创建Servlet的过程:

1)截取网络请求的Url,和url_pattern的值一一进行比较,然后找到对应的Servlet。

2)根据Servlet-class创建Servlet对象,调用init()方法,进行servlet的初始化,然后调用service()方法。

3)将处理好的数据放到response对象的缓存中;从Response对象的缓存中拿到数据,按照http协议的要求组织数据,发送到浏览器。

 

Servlet的生命周期

方法的调用顺序init---->service---->destroy

init()方法和destroy()方法只会调用一次;service方法会反复不断的调用。

默认调用带参数的init()方法,用于初始化。

默认情况下,servlet对象在第一次请求的时候调用构造函数创建, 创建之后自动调用带参的init方法,然后调用service方法.destroy方法在停止服务器或者停止应用的时候调用。整个过程中,init方法和destroy方法只会调用一次,而service方法会反复调用。


★什么时候创建servlet对象:当浏览器第一次访问web应用程序时,创建servlet对象。什么时候销毁servlet对象。
★在用户通过浏览器第一次访问web网站时,tomcat服务器会匹配网址中的资源地址,如果能够匹配到<url-partern>,就创建servlet对象,如果匹配不到,就是用服务器默认的servlet对象。此时servlet对象才成为web应用程序的组成部分,由此对象负责web应用与浏览器之间的请求与响应,相当于中间层。
★可能会出现一个servlet对应多个<url-parttern>的情况。即在浏览器地址栏中输入不同的网址,对应同一个servlet对象。
★先有配置文件,再有servlet对象(创建项目后,创建一个servlet对象)。
可以通过配置web.xml文件来改变创建servlet的时机.配置如下


servlet的创建问题

创建一个servlet有3中方式:

1)     采用实现servlet接口, 然后创建类的实例servlet对象(不推荐)

2)     采用继承GenericServlet类(抽象类 不推荐) 支持所有的传输协议

3)     采用继承HttpServlet(抽象类推荐) 只支持Http传输协议,专门用于处理通过http协议发送的请求和相应

在继承自HttpServlet抽象类的自定义类中,不要重写service()方法。此service()方法具有专门的用途:判断用户以哪种请求方式访问服务器端资源,主要用于请求转发。


Servlet:
理论上:servlet是一个接口,代表一种“响应规范”。因为它是一个接口,所以要使用它的实现类对象。
实际上:servlet代表一个java应用程序。
 
“请求重定向”与”请求转换”之间的区别:请求重定向是客户端行为,浏览器地址栏中的网址要发生;请求转换是服务器的行为,浏览器地址栏中的地址不会发生改变。
 
网址:协议+域名+端口号+应用目录+资源地址+资源名称。
如: http://localhost:8080/aaa/1.html。
 
第一个到达服务器的 HTTP 请求被委派到 Servlet 容器,里面装的是servlet对象。
Servlet 容器在调用 service() 方法之前加载 Servlet。
然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
Servlet是位于Web 服务器内部的服务器端的Java应用程序。
Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。
 
应用
url的写法注意:
客户端跳转:(由浏览器发出的请求)  一定需要在地址前加应用的名称
服务端跳转: (由服务端发出的请求)  不需要在地址前加应用的名称
应用:
1)实现数据共享。(全局只有一个ServletContext对象)
2)获取全局配置参数。进行全局参数配置
<context-param>  //必须放在<Servlet>标签的外面   param中的数据都是一键值对的形式存在。
<param-name>name</param-name>
<param-value>小龙女</param-value>
<param-name>age</param-name>
<param-value>18</param-value>
</context-param>

servlet创建的两种时机(☆)
1)服务器启动的时候创建,2)有请求到达时创建
<load-on-startup>10<load-on-startup>
1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
2)它的值必须是一个整数,表示servlet应该被载入的顺序
2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载(已经测试过)。
5)当值相同时,容器就会自己选择顺序来加载。

Url配置
由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
<servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。 
一个<servlet-mapping>元素用于映射Servlet的对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。
配置url-pattern有两种方式:
1)以/开头,/代表了工程路径  2)以*开头,后面必须添加后缀名。
<url-pattern>/*<url-pattern> <url-pattern>*.abc<url-pattern> 只要是以abc结尾的都能访问当前url-pattern对应的Serlvet
注意:
1)<url-pattern>/*.abc<url-pattern> 这种url配置是不被允许的。
2)同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。 

Servlet的运行过程
web浏览器发出http请求,web容器调用Servlet的service(Request,response)方法进行请求分发;
读取Request对象,拿到请求的信息;通过response对象写入响应信息,然后返回给wab容器,web容器根据http协议组织好数据格式,返回给客户端浏览器。
Request中包含请求头,请求体;response中包含响应头,响应体。
Tomcat的作用是什么?进行请求转发,把响应结果按照http协议的格式组织,然后返回给浏览器。

缺省的Servlet
1)如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。
2)凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。

Servlet的线程安全: 
1)当多个客户端并发访问同一个Servlet时,Web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
doGet() doPost()方法的执行是需要一段时间的。
2)如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。这样也会有问题,多个请求可能出现排队现象,造成服务器端响应速度慢。
如何解决呢:合理决定在Servlet中定义的变量的作用域。把全局变量修改成doGet()方法中的局部变量,每次都进行初始化  int a=0;a++。

Servlet核心类图
Servlet接口  ServletConfig接口  ServletContext接口
Servlet接口的实现类GenericServlet(抽象类)
HttpServlet继承自GenericServlet,也是抽象类

获取ServletConfig对象
1)在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
2)当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
1)使用带参数的init()方法获取ServletConfig
2)采用Servlet实例进行获取
注意:
一个init-param只能配置一个键值对
当前web.xml文件中的Servlet节点下,需要有<init-param>
使用ServletConfig:使用ServletConfig对象获取配置文件里的参数

    <servlet>        <servlet-name>ServletResponse</servlet-name>        <servlet-class>servertest.ServletResponse</servlet-class>        <init-param>            <param-name>陈如水</param-name>            <param-value>君临天下</param-value>        </init-param>        <init-param>            <param-name>秦珍珍</param-name>            <param-value>十里桃花</param-value>        </init-param>    </servlet>

        //ServletConfig sc = getServletConfig();        //String name = sc.getInitParameter("陈如水");        //System.out.println(name+"text");        //以枚举的形式获取所有配置键的集合 Enumeration枚举类的使用        //Enumeration<String> params = sc.getInitParameterNames();        //while (params.hasMoreElements()) {        //    String content = params.nextElement();        //    System.out.println(content + ":" + sc.getInitParameter(content));        //}


ServletContext对象:作为域对象使用,获取全局的配置参数,
1)WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
2)通过ServletConfig.getServletContext方法获得ServletContext对象。
3)由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。

域对象
所谓的域,起始就是一个容器,它里面有一个map对象,所有的域对象都提供三个方法
void setAttribute(key,value)
void removeAttribute(key)
Object getAttribute(key)
里面的数据是以键值对的形式存在的

获取ServletContext对象
1)采用ServletConfig对象获取
2)采用Servlet实例获取
3)采用request.getSession.getServletContext()进行获取。
无论采用何种方式获取ServletContext对象,获取的都是同一个对象。

        //获取ServletContext对象(这三个方法获取的对象是同一个)        //ServletContext servletContext = this.getServletConfig().getServletContext();        //ServletContext servletContext1 = this.getServletContext();        //ServletContext servletContext2 = request.getServletContext();

ServletContext对象的应用

1)把ServletContext当做域对象进行使用
2)通过ServletContext获取全局的配置参数
3)通过ServletContext进行请求转发
4)通过ServletContext获取资源文件

    <!--web应用程序全局的配置参数,将来会在这里配置很多内容,各种web框架的引用-->    <context-param>        <param-name>name</param-name>        <param-value>小龙女</param-value>    </context-param>    <context-param>        <param-name>age</param-name>        <param-value>18</param-value>    </context-param>

        //把ServletContext当做域对象进行使用        //String name = (String) servletContext.getAttribute("name");        //System.out.println(name);        //通过ServletContext获取全局的配置参数(获取单个配置参数)        //ServletContext servletContext = getServletContext();        //String age = servletContext.getInitParameter("age");        //System.out.println(age);        //ServletContext servletContext = this.getServletContext();        //Enumeration<String> names = servletContext.getInitParameterNames();        //while (names.hasMoreElements()) {        //    //names:表示枚举值,内部是键值对        //    String key = names.nextElement();        //    System.out.println(key + ":" + servletContext.getInitParameter(key));        //}        //通过ServletContext进行请求转发(获取请求转发器,转发到新的web资源)        //这种请求转发很少使用,Request对象中自带请求转发的方法了        //ServletContext servletContext = this.getServletContext();        //servletContext.setAttribute("test","请求转发");        //RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/ServletResponse8");        //requestDispatcher.forward(request,response);        //获取资源文件的三种方式(里面全部都是键值对, 资源文件和配置文件是不一样的)        //获取全局对象        ServletContext sc = this.getServletContext();        //获取资源文件的路径(相对路径)        String path = sc.getRealPath("/p1.properties");        //读取资源文件中的数据        Properties properties = new Properties();        properties.load(new FileInputStream(new File(path)));        System.out.println(properties.getProperty("s001"));
//请求转发之后,获取资源
  ServletContext sc = this.getServletContext();        String test = (String) sc.getAttribute("test");        System.out.println(test);


原创粉丝点击