zoukankan      html  css  js  c++  java
  • 11_Servlet的一些细节知识点

    【Servlet的细节知识点1-----一个Servlet映射到多个URL】

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

    如下:

    [ 工程截图 ]

    [ web.xml ]

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns="http://java.sun.com/xml/ns/javaee" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
             id="WebApp_ID" version="3.0">
      <display-name>HelloServlet</display-name>
      
      <servlet>
          <servlet-name>ServletDemo01</servlet-name>
          <servlet-class>com.Higgin.servlet.ServletDemo01</servlet-class>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>ServletDemo01</servlet-name>
          <url-pattern>/higgin.html</url-pattern>     <!--伪html-->
      </servlet-mapping>
      
      <servlet-mapping>
          <servlet-name>ServletDemo01</servlet-name>
          <url-pattern>*.do</url-pattern>    <!-- 匹配所有后缀为.do的URL -->
      </servlet-mapping>
    </web-app>

    [ ServletDemo01.java ]

    package com.Higgin.servlet;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    //@WebServlet("/ServletDemo01")
    public class ServletDemo01 extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("ServletDemo01----doGet");
            System.out.println(request.getRequestURL());  //获取客户端发出请求的URL
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
    }

    [ 运行结果 ]

    1.浏览器URL输入  http://localhost:8080/HelloServlet/higgin.html

    2.浏览器URL输入http://localhost:8080/HelloServlet/adfcvsd.do (只要是.do后缀)

    【Servlet的细节知识点2-----通配符*】

    Servlet映射到url中可以使用*通配符,但是只能有两种固定的格式:

    格式一: *.扩展名                                    例子:  *.do

    格式二: 正斜杠“/”开头并以"/*"结尾             例子: /action/*

    【Servlet的细节知识点3-----在修改web.xml时,无需重启TomCat的原因】

    我们打开Tomcat服务器所在的conf/context.xml

    <WatchedResource>WEB-INF/web.xml</WatchedResource>这句配置保证JavaWeb工程在web.xml被修改时,tomcat服务器会自动加载修改后的web.xml。

    【Servlet的细节知识点4-----关于映射关系再深入】

    【Servlet的细节知识点5-----Servlet内各个方法调用细节】

         Servlet是一个供其它java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行由Servlet引擎来控制和调度。

      针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,Servlet实例对象才会被销毁。

      在Servlet的整个生命周期内,Servlet的init方法只被调用一次。

      而对于一个Servlet的每次访问请求都导致Servlet引擎调用一次Servlet的service()方法。

      对于每次访问请求,Servlet引擎都会创建一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service()方法再根据请求方式分别调用doXXX方法。

    【Servlet的细节知识点6-----Servlet创建的时间改变<load-on-startup>

      默认情况下,第一次访问Servlet时创建Servlet对象,创建对象的时候会电泳构造方法和init方法。如果init方法的业务逻辑需要消耗比较长的时间,导致用户第一次访问Servlet时需要等待较长的时间。因此我们需要改变Servlet对象创建的时间:在TomCat服务器启动的时候就创建Servlet对象。

      如果在<servlet>元素中配置了一个<load-on-startup>元素,那么Web应用在程序启动时候,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。

    如下所示:(注意:值为正整数,数值越小,优先级越高!)

    <servlet>
          <servlet-name>FirstServlet</servlet-name>
          <servlet-class>com.Higgin.servlet.FirstServlet</servlet-class>
          <load-on-startup>2</load-on-startup>
     </servlet>

    用途:为Web应用写一个InitServlet,这个Servlet部署在TomCat服务器启动时装载,可以用来为整个Web应用创建必要的数据库表和数据。

    【Servlet的细节知识点7-----缺省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。

    * 当访问Tocat服务器中的某个静态HTML和图片时,实际上访问的就是这个缺省的Servlet。

    默认的Servlet的作用:用于解析Web应用下的静态资源。

    [ 浏览器输入一个资源名称的时,查找资源的顺序 ]

    1.首先,在当前web应用下的web.xml文件中查找是否有匹配的url-pattern。

    2.如果匹配到了,执行对应的Servlet(动态资源)。

    3.如果没有匹配到,就交给TomCat服务器默认的Servlet去处理。

    4.默认Servlet回到当前的web.xml应用下读取对应的名称的静态资源文件。

    5.如果读到对应的静态资源文件,就把内容返回给浏览器。

    6.如果没有读到对应的静态资源文件,就返回404的错误页面。

    结论:先找动态资源,在去找静态资源!

    【Servlet的细节知识点7-----Servlet线程安全问题】

    [引发的原因]

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

    [避免Servlet并发问题建议]

    1.尽量不要在Servlet类中使用成员变量

    2.如果要使用成员变量,那么就要给成员变量的代码块加上代码锁,尽量缩小同步锁的范围,以避免因为同步代码并发执行效率的降低。

    【Servlet的细节知识点8-----关于init方法】

    在GenericServlet中,有两个init方法。

      有参数的init方法:该方法是servlet的四个生命周期方法中的一个。由Tomcat服务器默认调用的初始化方法。在GenericServlet的实现中,该方法会调用无参数的init方法。

      无参数的init方法:该方法是给我们开发者去覆盖的,用于实现初始化逻辑的方法。

    结论:如果要编写Servlet的初始化逻辑,只需要覆盖无参数的init方法即可。

  • 相关阅读:
    Python程序中的线程操作-concurrent模块
    python程序中的进程操作-进程间的数据共享
    有几个消费者就需要发送几次结束信号
    python进程池
    Python程序中的线程操作-concurrent模块
    Python程序中的线程操作-线程队列
    Python程序中的线程操作-守护线程
    进程操作-进程池
    进程池版socket并发聊天
    使用多进程请求多个url来减少网络等待浪费的时间
  • 原文地址:https://www.cnblogs.com/HigginCui/p/5954995.html
Copyright © 2011-2022 走看看