• 细说Servlet


    一、如何开发一个Servlet

    1、编写Java类,继承HttpServlet类为什么要继承这个HttpServlet类呢?所有的Servlet类都要实现Servlet接口,GenericServlet实现了Servlet接口,但是这个类没有具体协议,所以HttpServlet继承了GenericServlet类,因此我们在编写Servlet类的时候,我们只需继承HttpServlet类,覆盖里边我们要用到的方法就可以。)

    2、重写doGET()和doPost方法

    3、Servlet程序由tomcat服务器运行。

      3.1 Servlet程序的class码拷贝到WEB-INF下边的classes目录里

      3.2 在web.xml 文件中进行配置

    部署web.xml文件

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

    <servelet>
            <!-- 给Servlet取名,可以任意取名 -->
            <servelet-name>Hello</servelet-name>
            <!-- 指明servlet的路径,就是servlet的包+类名 -->
            <servlet-class>com.lyjs.Hello</servlet-class>
    </
    servelet>

    <
    servelet-mapping> <!--  servlet的内部名称,一定要和上面的内部名称保持一致!! --> <servelet-name>Hello</servelet-name> <!-- 浏览器中输入的url,可以随意取名 -->
         
    <url-pattern>/Hello</url-pattern>
    </
    servelet-mapping>

    3.3一对多映射

    同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。这样就可以通过不同的URL来访问同一个Servlet。

    <!--Hello被映射到/Hello-->
    <servelet-mapping>
            <servelet-name>Hello</servelet-name>
            <url-pattern>/Hello</url-pattern>
    </servelet-mapping>
    
    
    <!--Hello被映射到/My/Hello-->
    
    <servelet-mapping>
            <servelet-name>Hello</servelet-name>
            <url-pattern>/My/Hello</url-pattern>
    </servelet-mapping>
    
    
    <!--所以可以通过两个URL,都可以访问到Hello这个Servlet-->

    3.4、映射匹配问题:

                       url-pattern                   浏览器输入
    精确匹配             /first                 http://localhost:8080/day10/first
                        /itcast/demo1          http://localhost:8080/day10/itcast/demo1
    
    模糊匹配             
      
                /*   http://localhost:8080/day10/任意路径 /itcast/* http://localhost:8080/day10/itcast/任意路径 *.后缀名   http://localhost:8080/day10/任意路径.do *.do *.action *.html(伪静态)

    注意:

    1. url-pattern要么以 / 开头,要么以 * 开头,例如:itlyjs 为非法路径。
    2. 在Servlet中模糊匹配有两种固定的形式:一种是"*.扩展名",另一种是以正斜杠(/)开头并以"/*"结尾。不能同时使用两种模糊匹配,要么/* ,要么 *.do. 例如 /itlyjs/*.do是非法路径。
    3. 当有输入的URL有多个Servlet同时匹配的时候:精确匹配优先,(长的最像的优先匹配,),以后缀名结尾的模糊url-pattern优先级最低

    练兵场地

    1. Servlet1 映射到 /abc/*
    2. Servlet2 映射到 /*
    3. Servlet3 映射到 /abc
    4. Servlet4 映射到 *.do

    问题:

    1. 当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应,Servlet引擎将调用Servlet1。
    2. 当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应,Servlet引擎将调用Servlet3
    3. 当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应,Servlet引擎将调用Servlet1
    4. 当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应, Servlet引擎将调用Servlet2。
    5. 当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应, Servlet引擎将调用Servlet2。

    优先级:完全匹配>*匹配>后缀名匹配 

    四、Servlet缺省路径

    servlet的缺省路径(<url-pattern>/</url-pattern>)是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件。

    问题: URL输入http://localhost:8080/day10/index.html 如何读取文件?

    1. 到当前day10应用下的web.xml文件查找是否有匹配的url-pattern
    2. 如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理
    3. DefaultServlet程序到day10应用的根目录下查找是存在一个名称为index.html的静态文件。
    4. 如果找到该文件,则读取该文件内容,返回给浏览器。
    5. 如果找不到该文件,则返回404错误页面。

    总结:web应用的资源分为两类,动态资源和静态资源。tomcat先找动态资源,再找静态资源

    五、Servlet的生命周期

    1. 构造方法:创建Servlet对象的时候调用。默认情况下,第一次访问Servlet的时候创建Servlet对象,只调用1次。证明Servlet对象在tomcat是单例的。
    2. init方法:创建完Servlet对象的时候调用,只调用1次
    3. service方法:每次发出请求时调用1次。调用n次
    4. destory方法:销毁Servlet对象的时候调用,停止服务器或重新部署web应用时销毁Servlet对象,只调用1次。

    文字描述:(可以跳过)

      Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调 用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个 新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service 方法再根据请求方式分别调用doXXX方法。

    六、伪代码演示Servlet的生命周期

    Tomtcat内部代码运行:
                1)通过映射找到到servlet-class的内容,字符串: gz.itcast.a_servlet.FirstServlet
                2)通过反射构造FirstServlet对象
                        2.1 得到字节码对象
                        Class clazz = class.forName("gz.itcast.a_servlet.FirstServlet");
                        2.2 调用无参数的构造方法来构造对象
                        Object obj = clazz.newInstance();     ---1.servlet的构造方法被调用
                3)创建ServletConfig对象,通过反射调用init方法
                        3.1 得到方法对象
                        Method m = clazz.getDeclareMethod("init",ServletConfig.class);
                        3.2 调用方法
                        m.invoke(obj,config);             --2.servlet的init方法被调用
                4)创建request,response对象,通过反射调用service方法
                        4.1 得到方法对象
                        Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
                        4.2 调用方法
                        m.invoke(obj,request,response);  --3.servlet的service方法被调用
                5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法
                        5.1 得到方法对象
                        Method m = clazz.getDeclareMethod("destroy",null);
                        5.2 调用方法
                        m.invoke(obj,null);            --4.servlet的destroy方法被调用

    七、Servlet的自动加载:<load-on-startup>  

    默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用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>

    标签里边的数字代表了调用的优先级,数字越小,越先被调用。

    八、Servlet线程安全问题。

    注意: Servlet对象在tomcat服务器是单实例多线程的。

    因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

    解决办法:

    1. 把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)
    2. 建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

    九、ServletConfig对象,学习ServletConfig对象(点击我,去学习)

    十、ServletContext对象,学习ServletContext对象(点击我,去学习)

  • 相关阅读:
    真的是简单、简洁、简易、简明之道!!!
    HashMap源码解读
    Jenkins Pipeline
    C语言二级指针free|一级指针存储内存地址
    openjdk编译和调试,JVM编译调试
    java linux和win jdk安装包jdk1.6、jdk1.7和jdk1.8 7u80 8u181 8u161
    关于java代码打包成jar在控制台运行变慢的问题
    Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen
    mongodb副本集
    condition
  • 原文地址:https://www.cnblogs.com/lyjs/p/4868906.html
Copyright © 2020-2023  润新知