• Servlet知识点总结-DX的笔记


    学习要点

    • servlet概念及相关接口简介
    • servet 执行过程
    • servlet路径映射
    • 缺省servlet --应用
    • servlet生命周期(重点) --理解(重点)
    • Servlet自动加载
    • Servlet线程安全
    • servletConfig对象
    • Servlet相关接口详解
    • ServletContext对象 --知识点

    如何开发Servlet

    Servlet的开发流程

    • 写一个普通类,继承HttpServlet类

    • 重写doxx方法

    • 在web.xml中配置servlet

      • <servlet>
            <servlet-name>LoginServlet</servlet-name>				servlt的别名
            <servlet-class>dx.servlet.LoginServlet</servlet-class>	servlet的全限定类名字符串
        </servlet>
        <servlet-mapping>
            <servlet-name>LoginServlet</servlet-name>				指定servlt的别名
            <url-pattern>/hello</url-pattern>						分配一个url供用户调用
        </servlet-mapping>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8

    Servlet的执行流程

    • 浏览器输入网址敲回车,浏览器先在本机查找host.txt文件,这个文件保存了一些默认的域名与ip的映射.
    • 如果本机没有指定的映射,会向电信运营商提供的dns服务器发送请求,获取映射关系,返回对应的ip地址
    • 浏览器使用ip地址替换用户输入的网址中的域名,接着才会正式访问资源
    • 向真正的资源发送请求,请求会被web服务器接收
    • Web服务器会解析请求,获取访问的资源路径
    • Web服务器会根据地址优先查找动态资源(servlet)
    • Web服务器会在web.xml文件中查找哪个servlet的url-pattern符合用户访问的地址
      • 找到
        • 会查找对应的servlet-name
        • 根据servlet-name找到对应的servlet-class
        • 找到class根据里面的全限定类名,使用反射创建servlet对象
        • 调用对象的service方法,同时将请求的内容使用HttpservletRequest封装,将响应的内容使用HttpServletResponse封装作为参数,传入service方法
        • service方法根据请求方式调用对应的doxxx方法
      • 找不到
        • 没有对应的servlet处理请求,会根据路径查找静态资源
        • 如果找到,显示资源
        • 如果没有找到,显示404
    • 查找规则:优先查找动态资源,其次才是静态资源

    Servlet的映射路径

    映射路径的配置规则:1.精准匹配 2.模糊匹配

    精确匹配

    • url与servlet之间的关系是一对一的
    • 注:一个servlet可以配置多个url
    • 写法如下:
      • /app1
      • /app1.action
      • /app.do
      • /app1.html:伪静态化
      • /user/app1
    • 不管如何写,都将读取为String类型

    模糊匹配

    • url与servlet之间的关系是多对一的
    • 写法如下:
      • /* 多个url匹配app1servlet
      • *.do 以.do结尾的url匹配app1servlet
      • /user/* 以/user/开头的url匹配app1servlet
    • 以下写法是不可以的,要按照上面的格式写
      • /h* ❌
      • /h.* ❌

    思考:/与/*的的效果是否相同?

    • 作用相似,但优先级不同
    • /属于精准匹配,/*属于模糊匹配
    • /的优先级更高
    • (此答案不权威)

    servlet缺省路径

    • 现象:输入网址知识/的话,会默认打开index.jsp

    • 作用:通过设置缺省的路径,可实现输入域名即可访问入口界面(首页)的效果

    • 原理:查看tomcat的conf目录的web.xml文件,代码如下

    • <servlet>
              <servlet-name>default</servlet-name>
              <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
      </servlet>
      <servlet-mapping>
              <servlet-name>default</servlet-name>
              <url-pattern>/</url-pattern>
      </servlet-mapping>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 这个功能的实现,是由一个名为DefaultServlet的servlet在起作用

    • 缺省servlet会默认查找配置文件中的欢迎页面列表,如果找到就显示,找不到显示404

    • <welcome-file-list>
              <welcome-file>index.html</welcome-file>
              <welcome-file>index.htm</welcome-file>
              <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      
      • 1
      • 2
      • 3
      • 4
      • 5

    如何修改首页?

    • 方法一

      • 直接修改tomcat下的web.xml文件中的welcome-file-list代码即可
      • 不推荐,因为tomcat的配置文件针对所有的项目.
    • 方法二

      • 在自己项目的web.xml文件中添加这段配置信息即可,修改仅针对当前项目

      • <welcome-file-list>
                <welcome-file>hello.html</welcome-file>
        </welcome-file-list>
        
        • 1
        • 2
        • 3
    • 注意:如果自己配置的servlet的url也是/,那么会覆盖缺省servlet的配置

    Servlet的生命周期

    对象的生命周期

    • 使用反射或者new创建对象
    • 使用set方法或者代码块初始化属性
    • 调用成员方法
    • 失去引用被回收销毁

    Servlet的四个生命周期方法

    • 构造方法 服务器启动后,用户第一次访问时 1次
    • init方法 对象创建后执行 1次
    • doxx方法 用户访问时执行 N次
    • destroy方法 服务器关闭的时候 1次

    注意:

    • Servlet是单例多线程的
    • Servlet对象的创建延迟到用户第一次访问的时候

    Servlet的自动加载

    • servlet的对象默认是用户第一次访问的时候创建的,我们希望对象随着tomcat的启动而创建

    • 实现自动加载:

      <load-on-startup>1</load-on-startup>
      
      • 1
    • 注意:

      • 配置自动加载信息的代码中,可以指定一个正整数,数值越小启动的优先级越高.
      • 如果需要配置但是不知道配置什么值,我们就指定为1
    • servlet是单例多线程的,体现了设计模式的单例模式

    Servlet的多线程并发问题

    • 如果在如果在servlet中定义成员变量.并在doxx方法中进行写操作,可能会出现线程安全问题.
    • 解决办法:对可能出现问题的代码加锁

    ServletConfig对象

    • 作用:ServletConfig对象封装了servlet的配置信息
    • 创建:tomcat创建的,执行init方法的时候创建的.
    • 获取:tomcat创建后,该对象作为形参传入init方法中,所以在init方法中直接就能使用
    • 注意:每个servlet会产生一个servletConfig对象,servlet之间不会交叉访问其他Config对象

    举个例子

    • 配置初始化参数

    • <servlet>
          <servlet-name>app4</servlet-name>
          <servlet-class>com.bjpowernode.servlet.App4Servlet</servlet-class>
          <init-param>
              <param-name>debug</param-name>
              <param-value>0</param-value>
          </init-param>
          <init-param>
              <param-name>listings</param-name>
              <param-value>false</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>app4</servlet-name>
          <url-pattern>/app4</url-pattern>
      </servlet-mapping>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    • 获取初始化参数

    • // 1. 获取servlet-name属性
      String name = config.getServletName();
      // 2. 获取servlet的初始化参数
      String debug = config.getInitParameter("debug");
      String listings = config.getInitParameter("listings");
      // 3.获取所有的初始化参数
      Enumeration<String> names = config.getInitParameterNames();
      while (names.hasMoreElements()){
          String key = names.nextElement();
          String value = config.getInitParameter(key);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    ServletContext对象

    • ServletContext:servlet的上下文对象,servlet的运行环境

    • 创建: tomcat在web容器启动的时候创建,只会创建一个

    • 获取:

      • 在init方法中,通过servletConfig对象的getServletContext()获取

      • 在doxx方法中,通过Request对象的getServletContext()获取

        ServletContext context = req.getServletContext();
        
        • 1

    ServletContext对象的核心API

    • 域相关的方法:

      • getAttribute(String key): 根据key获取值
      • setAttribute(String key,Object value): 添加一个键值对
      • removeAttribute(String key): 根据key删除键值对
    • 获取初始化参数相关:

      • getInitParameter(String name): 根据初始化参数名称获取值

        <!--  web.xml中配置全局初始化参数  -->
        <context-param>
            <param-name>user</param-name>
            <param-value>root</param-value>
        </context-param>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        // 获取全局初始化参数
        String user = context.getInitParameter("user");
        
        • 1
        • 2
      • getInitParameterNames(): 获取所有的初始化参数名称集合

    • 其他

      • getContextPath() 获取web应用的路径
      • getRealPath(String path) 获取资源的真实路径
      • getResourceAsStream(String path) 根据资源的相对路径获取内容,内容以自己输入流的方式获取
      • getRequestDispatcher() 使用转发的方式跳转页面

    获取真实路径

    • web项目中,使用读取资源的时候需要绝对路径,相对路往往找不到资源

      // 1.获取servletContext对象
      ServletContext context = req.getServletContext();
      // 2.创建输入流读取资源文件
      //方式一
      String path = context.getRealPath("/upload/db.properties");//这里的参数是一个相对路径
      FileInputStream fis = new FileInputStream(path);
      //方式二
      InputStream fis = context.getResourceAsStream("/upload/db.properties");
      // 3.创建Properties对象加载文件内容
      Properties properties = new Properties();
      properties.load(fis);
      // 4.获取文件内容
      String user = properties.getProperty("user");
      String pass = properties.getProperty("pass");
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    • 配置文件一般保存在resources目录下,最终会被编译在classes目录下面,所以classes目录下的配置文件一般可以使用如下路径:/WEB-INF/classes/db2.properties

    • 如果读取classes目录下的文件,可以使用当前类的类加载器读取:

      InputStream is = MyServlet.class.getClassLoader().getResourceAsStream("db2.properties");
      
      • 1

    域对象

    • 作用:为服务端程序共享数据提供的共享空间
    • 4个域对象(从小到大排列)
      • pageContext
      • request
      • session
      • servletContext
    • 域对象的结构是Map类型的<String,Object>
    • 常用方法
      • getAttribute(String key): 根据key获取值
      • setAttribute(String key,Object value): 添加一个键值对
      • removeAttribute(String key): 根据key删除键值对
    • servletContext域对象的作用范围是整个项目,每个运行的项目都会产生一个context对象.

    转发

    • 转发的两种实现方式

      context.getRequestDispatcher("/app11").forward(req,resp);
      req.getRequestDispatcher("/app1.html").forward(req,resp);
      
      • 1
      • 2
    • 举例

       // 1.获取servletContext对象
       ServletContext context = req.getServletContext();
       // 2.使用转发访问app1.html
       context.getRequestDispatcher("/app1.html").forward(req,resp);
       // 3.使用转发访问servlet
       context.getRequestDispatcher("/app11").forward(req,resp);
       // 4.使用转发访问baidu
       //java.lang.IllegalArgumentException: 路径[https://www.baidu.com]不以“/”字符开头
       // 转发的资源只能是项目内的资源
       context.getRequestDispatcher("https://www.baidu.com").forward(req,resp);
       // 5.使用请求实现转发操作
       req.getRequestDispatcher("/app1.html").forward(req,resp);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 转发和重定向的区别:

      • 转发的资源只能是项目内部的(静态和动态资源)

        重定向的资源可以是内部的,可以是外部的

    • 转发只请求一次,转发访问新资源使用的是原有的请求和响应,所以只请求了一次

      重定向请求了两次,重定向访问新资源使用新的请求和响应,所以请求了两次

      • 转发访问资源不会导致地址栏中的url发生改变

        重定向访问资源会导致地址栏中的url发生改变

  • 相关阅读:
    【Python毕业设计源码】diango大学生职业推荐平台
    6. Java 运算符
    【数值计算汇总】js前端数值计算校验转换
    A-Level经济真题每期一练(54)
    CSC公派遭美德拒签|计算机专业老师终赴意大利都灵理工大学访学
    JUC第二十五讲:JUC线程池-CompletableFuture 实现原理与实践
    使用Java操作Redis
    python经典百题之判断星期几
    vue-json-editor
    flex 实现多行项目动态堆叠,随着屏幕尺寸而扩展减少
  • 原文地址:https://blog.csdn.net/qq_43528471/article/details/125509758