zoukankan      html  css  js  c++  java
  • 如何开发一个Servlet

    1 如何开发一个Servlet

    1.1 步骤:

    1)编写java类,继承HttpServlet

    2)重新doGetdoPost方法

    3Servlet程序交给tomcat服务器运行!!

    3.1 servlet程序的class码拷贝到WEB-INF/classes目录

    3.2 web.xml文件中进行配置

    <!-- 配置一个servlet -->

      <!-- servlet的配置 -->

      <servlet>

       <!-- servlet的内部名称,自定义。尽量有意义 -->

       <servlet-name>FirstServlet</servlet-name>

       <!-- servlet的类全名: 包名+简单类名 -->

       <servlet-class>gz.itcast.a_servlet.FirstServlet</servlet-class>

      </servlet>

      

      

      <!-- servlet的映射配置 -->

      <servlet-mapping>

       <!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->

       <servlet-name>FirstServlet</servlet-name>

       <!-- servlet的映射路径(访问servlet的名称) -->

       <url-pattern>/first</url-pattern>

      </servlet-mapping>

    问题:访问次URL:  http://localhost:8080/day10/first  

    前提: tomcat服务器启动时,首先加载webapps中的每个web应用的web.xml配置文件。

    http://: http协议

    localhost 到本地的hosts文件中查找是否存在该域名对应的IP地址

    127.0.0.1

    8080    找到tomcat服务器

    /day10     tomcatwebapps目录下找 day10的目录

    /first    资源名称。

    1)在day10web.xml中查找是否有匹配的url-pattern的内容(/first

    2)如果找到匹配的url-pattern,则使用当前servlet-name的名称到web.xml文件中查询是否相同名称的servlet配置

    3)如果找到,则取出对应的servlet配置信息中的servlet-class内容:

    字符串: gz.itcast.a_servlet.FirstServlet

     

    通过反射:

    a)构造FirstServlet的对象

    b)然后调用FirstServlet里面的方法

    2 Servlet的映射路径

    <servlet-mapping>

       <!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->

       <servlet-name>FirstServlet</servlet-name>

       <!-- servlet的映射路径(访问servlet的名称) -->

       <url-pattern>/first</url-pattern>

      </servlet-mapping>

                        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(伪静态)

    注意:

    1url-pattern要么以 / 开头,要么以*开头。  例如, itcast是非法路径。

    2)不能同时使用两种模糊匹配,例如 /itcast/*.do是非法路径

    3)当有输入的URL有多个servlet同时被匹配的情况下:

    3.1 精确匹配优先。(长的最像优先被匹配)

    3.2 以后缀名结尾的模糊url-pattern优先级最低!!!

    3 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处理

    3DefaultServlet程序到day10应用的根目录下查找是存在一个名称为index.html的静态文件。

    4)如果找到该文件,则读取该文件内容,返回给浏览器。

    5)如果找不到该文件,则返回404错误页面。

    结论: 先找动态资源,再找静态资源。

    4 Sevlet的生命周期(重点)

    4.1 引入

    Servlet的生命周期: servlet类对象什么时候创建,什么时候调用什么方法,什么时候销毁。

    以前的对象: new Student(); stu.study();   stu=null;

    Servlet程序的生命周期由tomcat服务器控制的!!!!

    4.2 Servlet重要的四个生命周期方法

    构造方法: 创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象 只调用1次。证明servlet对象在tomcat是单实例的。

    init方法: 创建完servlet对象的时候调用。只调用1次。

    service方法: 每次发出请求时调用。调用n次。

    destroy方法: 销毁servlet对象的时候调用。停止服务器或者重新部署web应用时销毁servlet对象。

    只调用1次。

    4.3 伪代码演示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.servletinit方法被调用

    4)创建requestresponse对象,通过反射调用service方法

    4.1 得到方法对象

    Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

    4.2 调用方法

    m.invoke(obj,request,response);  --3.servletservice方法被调用

    5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法

    5.1 得到方法对象

    Method m = clazz.getDeclareMethod("destroy",null);

    5.2 调用方法

    m.invoke(obj,null);            --4.servletdestroy方法被调用

    4.4 用时序图来演示servlet的生命周期

    5 Servlet的自动加载

    默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。

    改变servlet创建对象的时机: 提前到加载web应用的时候!!!

    servlet的配置信息中,加上一个<load-on-startup>即可!!

    <servlet>

        <servlet-name>LifeDemo</servlet-name>

        <servlet-class>gz.itcast.c_life.LifeDemo</servlet-class>

        <!-- servlet对象自动加载 -->

        <load-on-startup>1</load-on-startup>  注意: 整数值越大,创建优先级越低!!

      </servlet>

    7 有参的init方法和无参的init方法

    8 Servlet的多线程并发问题

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

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

    解决办法:

    1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)

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

    Servlet学习:

     HttpServletRequest  请求对象:获取请求信息

     HttpServletResponse 响应对象: 设置响应对象

     ServletConfig对象    servlet配置对象

     ServletContext对象; servlet的上下文对象

    9 ServletConfig对象

    9.1 作用

    ServletConfig对象: 主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)

    9.2 对象创建和得到

    创建时机: 在创建完servlet对象之后,在调用init方法之前创建。

    得到对象: 直接从有参数的init方法中得到!!!

    9.3 servlet的初始化参数配置

      <servlet>

        <servlet-name>ConfigDemo</servlet-name>

        <servlet-class>gz.itcast.f_config.ConfigDemo</servlet-class>

        <!-- 初始参数: 这些参数会在加载web应用的时候,封装到ServletConfig对象中 -->

        <init-param>

         <param-name>path</param-name>

         <param-value>e:/b.txt</param-value>

        </init-param>

      </servlet>

        注意: servlet的参数只能由当前的这个sevlet获取!!!!

    ServletConfigAPI

    java.lang.String getInitParameter(java.lang.String name)  根据参数名获取参数值

    java.util.Enumeration getInitParameterNames()    获取所有参数

        ServletContext getServletContext()     得到servlet上下文对象

    java.lang.String getServletName()       得到servlet的名称

    10 ServletContext对象

    10.1 引入

    ServletContext对象 ,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一 ServletContext对象。

    10.2 对象创建和得到

    创建时机:加载web应用时创建ServletContext对象。

    得到对象: ServletConfig对象的getServletContext方法得到

    我们设计:

    创建ServletConfig对象

    public void init( ServletConfig configServletContext context ){  多了一个参数

    得到ServletConfig对象

    得到ServletContext对象;

    }

    Sun公司设计

    1)创建ServletContext对象   ServletContext  context = new ServletContext()

    2)创建ServletConfig对象   ServetConfig config = new ServletConfig();

                                                  config.setServletContxt(context);

    class  ServletConfig{

    ServletContext context;

    public ServletContext getServletContxt(){

    return contxt;

    }

    }

    public void init( ServletConfig config ){

    得到ServletConfig对象

    ServletConfig对象中得到ServletContext对象

    SerlvetContext context = config.getServletContext();

    }

    10.1 ServletContext对象的核心API(作用)

    java.lang.String getContextPath()   --得到当前web应用的路径

    java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数

    java.util.Enumeration getInitParameterNames()  

    void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法

    java.lang.Object getAttribute(java.lang.String name)  

    void removeAttribute(java.lang.String name)  

    RequestDispatcher getRequestDispatcher(java.lang.String path)   --转发(类似于重定向)

    java.lang.String getRealPath(java.lang.String path)     --得到web应用的资源文件

    java.io.InputStream getResourceAsStream(java.lang.String path)  

    10.3 得到web应用路径

    java.lang.String getContextPath()  用在请求重定向的资源名称中

    10.4得到web应用的初始化参数(全局)

    java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数

    java.util.Enumeration getInitParameterNames()  

    web应用参数可以让当前web应用的所有servlet获取!!!

    10.5域对象有关的方法

    域对象:作用是用于保存数据,获取数据。可以在不同的动态资源之间共享数据

    案例:   

    Servlet1                   Servlet2

            name=eric                     

    response.sendRedirect("/Servlet2?name=eric")             String request.getParameter("name");

    保存到域对象中            从域对象获取

    Student                  

    方案1: 可以通过传递参数的形式,共享数据。局限:只能传递字符串类型。

    方案2: 可以使用域对象共享数据,好处:可以共享任何类型的数据!!!!!

    ServletContext就是一个域对象!!!!

    保存数据:void setAttribute(java.lang.String name, java.lang.Object object)

    获取数据: java.lang.Object getAttribute(java.lang.String name)  

    删除数据: void removeAttribute(java.lang.String name)  

    ServletContext域对象:作用范围在整个web应用中有效!!!

    所有域对象:

    HttpServletRequet 域对象

    ServletContext域对象

    HttpSession 域对象

    PageContext域对象

    10.6 转发

     RequestDispatcher getRequestDispatcher(java.lang.String path)

    1)转发

     a)地址栏不会改变

     b)转发只能转发到当前web应用内的资源

    c)可以在转发过程中,可以把数据保存到request域对象中

    2)重定向

    a)地址栏会改变,变成重定向到地址。

    b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。

    c)不能再重定向的过程,把数据保存到request中。

    结论: 如果要使用request域对象进行数据共享,只能用转发技术!!!

    总结:

    Servlet生命周期(重点)

  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/burningmyself/p/7101210.html
Copyright © 2011-2022 走看看