• 7.3Servlet继承结构和运行过程


    ,,

    一个servlet在被初次访问的时候在服务器就会创建一个servlet对象

    为什么要模板修改是因为我们在用servlet文件的使用,总是有一些不用的信息,每次删除就太麻烦了,所以有模板修改,这样生成的servlet文件就是干净的了

    servlet的细节

    细节一:

                 由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

                  servlet标签称之为注册servlet标签,用于注册一个servlet ,注册servlet标签中添加子标签servlet-name和servlet-class,代表servlet的注册名称具体包名类路径(即servlet的物理路径)。

                  servlet-mapping标签称之为servlet映射标签。映射servlet标签中添加子标签servlet-name和url-pattern,分别用于指定已注册Servlet的名称Servlet的对外访问路径(即虚拟路径)。

             <servlet>
                <servlet-name>FirstServlet</servlet-name>
                <servlet-class>cn.tedu.FirstServlet</servlet-class>
             </servlet>
              <servlet-mapping>
                <servlet-name>FirstServlet</servlet-name>
                <url-pattern>/servlet/FirstServlet</url-pattern>
              </servlet-mapping>

    之所以书写成注册和映射servlet两部分,是因为

    i. 考虑以后可能有多个虚拟路径同时映射到真实的servlet身上,以上形式只需要书写映射servlet标签即可,相对来说,较为简单。

    II.servlet名称不允许重复。

     细节二:

     i.同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。

     ll.在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

              <servlet>
                <servlet-name>FirstServlet</servlet-name>
                <servlet-class>cn.tedu.FirstServlet</servlet-class>
              </servlet>
            
              <servlet-mapping>
                <servlet-name>FirstServlet</servlet-name>
                <url-pattern>/servlet/*</url-pattern>
              </servlet-mapping>
              
              <servlet>
                <servlet-name>FirstServlet</servlet-name>
                <servlet-class>cn.tedu.FirstServlet</servlet-class>
              </servlet>
            
              <servlet-mapping>
                <servlet-name>FirstServlet</servlet-name>
                <url-pattern>*.do</url-pattern>
              </servlet-mapping>

        servlet细节三--通配路径的优先级

                  • 对于如下的一些映射关系:

                         ○ Servlet1 映射到 /abc/*

                         ○ Servlet2 映射到 /*

                         ○ Servlet3 映射到 /abc

                         ○ Servlet4 映射到 *.do      (永远匹配级最低)

                  • 问题:

                         ○ 当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应

                                § Servlet引擎将调用Servlet1。

                         ○ 当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应

                                § Servlet引擎将调用Servlet3。

                         ○ 当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应

                                § Servlet引擎将调用Servlet1。    

                         ○ 当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

                                § Servlet引擎将调用Servlet2。

                         ○ 当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

                                § Servlet引擎将调用Servlet2。

                  • 注意:

                         ○ 虚拟路径与通配路径越相似的路径越优先采用。

                         *.do永远匹配级别最低。

           5. servlet细节四---load-on-startup标签

                  a. load-on-startup标签可以书写在注册servlet标签中。在load-on-startup标签中间可以添加一个数字,如果这个数字大于等于0,那么当前servlet会随着web应用的启动而加载。如果数字小于0,

                      则servlet不会随着web应用的启动而加载,仍然需要访问之后才会创建对象完成初始化。

                  b. 注意:load-on-startup标签中的数字表示优先级,数字越小,优先级越高,越优先启动。

                     Load-on-startup加载的servlet只是调用servlet init()方法创建servlet对象进行初始化。所以想要一些开启服务器就要启动的功能设置,需重写init方法

        <servlet>
            <servlet-name>invoker</servlet-name>
            <servlet-class>
                org.apache.catalina.servlets.InvokerServlet
            </servlet-class>
            <load-on-startup>2</load-on-startup>
    </servlet>

                   需求:在服务器启动的时候自动创建表格student,并添加表数据。

           6. servlet细节五---缺省servlet

                  在conf/web.xml中包含一个缺省servlet(defaultServlet),会随着tomcat服务器的启动而加载,负责所有web应用静态资源的加载,如果用户访问的资源路径不存在或者服务器报错,都会交给缺省servlet来处理。

                  缺省servlet的url-pattern配置为一个"/"

         

                    <servlet-mapping>
    
                                 <servlet-name>default</servlet-name>
    
                                 <url-pattern>/</url-pattern>
    
                    </servlet-mapping>

                  "/"为缺省servlet特有的虚拟路径形式,任何一个servlet如果配置虚拟路径为"/",那么当前servlet都会作为缺省Servlet进行工作。

                  a. 问题:"/"和"/*"意义上的区别:

                 i. "/"是缺省servlet的虚拟路径,一旦servlet配置这个虚拟路径,则会作为缺省servlet使用,负责静态资源和没人要的资源加载。

                "/*"是通配的虚拟路径形式,表示在*号的位置输入任意的内容都会与当前的路径匹配,所有的路径都会使用/*来通配,使用对应的servlet显示结果。

    Servlet细节七--servlet运行过程及生命周期

                  a. servlet运行过程:

                         i. 通过hosts文件或域名解析器,将域名解析为一个ip地址,找到对应的服务器,再通过端口号确定是哪一个服务器。

                         ii. 通过Host请求确定是当前服务器的哪一台虚拟主机。

                         iii. 通过请求行的请求资源名称部分,确定是哪一个web应用的虚拟路径。

                         iv. 通过请求行的请求资源名称部分,确定是当前web应用的哪一个web资源的虚拟路径。

                         再使用web资源的虚拟路径与web.xml文件中的url-patter作比较,确定是哪一个真实的servlet文件。

                         v. servlet返回的结果会放在response缓冲区中,在服务器内组织成一定结构之后,再发送给浏览器展示。

                  b. servlet生命周期

                         在servlet被初次访问的时候,会创建一个对象驻留在tomcat内存中。这个对象会重复使用。在对象创建之后,会立刻调用init方法完成初始化的操作。每一次访问servlet都会导致service方法执行,提供服务。在web应用被移除容器或者或者服务器关闭的情况下,servlet对象会被销毁,在销毁之前会自动调用destroy方法完成一些善后的操作。

    不能主动调用destroy来销毁servlet对象

           7. servlet细节六---线程安全问题

                  ○ 当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

                  ○ 如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。

                  ○ SingleThreadModel接口中没有定义任何方法,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。 

                  ○ 对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。

                  ○ 实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。

                  a. 线程安全问题的解决方案:

                         i. 多实用局部变量,少使用成员变量和静态变量。因为成员变量和静态变量都会引发线程安全问题。

                        II.合理加锁。锁一定要锁住关键部分代码,否则会降低代码的执行效率。

  • 相关阅读:
    redis 基本操作-python 使用redis-手机验证接口-发送短信接口
    登录-注册页面修订
    10-29 课堂笔记
    git 协作开发
    git 常规使用
    luffy-city 基础环境搭建(至轮播图前后台交互实现)-步骤目录
    偏移分页-游标(加密)分页-自定义过滤器-第三方过滤器插件(django-filter)
    drf 大总结
    739. Daily Temperatures
    617. Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/xuwangqi/p/11331422.html
Copyright © 2020-2023  润新知