《深入浅出 Servlet:Java Web 开发的基石》(二)

news/2024/12/24 2:51:45 标签: servlet, java, 前端
  1. ServletConfig(熟练)

ServletConfig对象对应web.xml文件中的<servlet>元素。例如你想获取当前Servlet在web.xml文件中的配置名,那么可以使用servletConfig.getServletName()方法获取!

你不能自己去创建ServletConfig对象,Servlet的init()方法的参数就是ServletConfig类型的。Tomcat在调用init()方法时,会传递ServletConfig对象。你可以在init()方法中使用它!

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>cn.tx.servlet.Servlet1</servlet-class>
    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <param-name>password</param-name>
        <param-value>txjava</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

String username = Cservletonfig.getInitParameter("username");
System.out.println("username:"+username);
Enumeration<String> parameterNames = servletConfig.getInitParameterNames();
while (parameterNames.hasMoreElements()){
    String element = parameterNames.nextElement();
    System.out.println(element+":"+servletConfig.getInitParameter(element));
}

添加了两个初始化参数,第一个参数的名称为paramName1,第一个参数的值为paramValue1;第二个参数的名称为paramName2,第二个参数值为paramValue2。

在<servlet>元素中可以加载多个<init-param>,每个<init-param>表示一个参数。<init-param>下有两个子元素:<param-name>和<param-value>,其中<param-name>表示参数的名称,而<param-value>元素参数的值。

注意,<init-param>是添加到<servlet>元素中,而不是<servlet-mapping>中。

  使用ServletConfig对象的getInitParameter(String paramName)方法可以获取指定参数名称的参数值。getInitParameterNames()方法返回所有参数的名字,返回值类型为Enumeration。

  1. Servlet路径映射(熟练)

关于Url-Pattern的配置:

  • 完全路径匹配  以/开头    例如  /aaa   /aaa/bbb  
  • 目录匹配 以/开头    例如  /aaa/*   /*   
  • 扩展名匹配 不能以/开头   例如  *.do   *.action  ....

优先级: 完全路径匹配 > 目录匹配 > 扩展名匹配

经典错误:  /*.do

举例:

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

  • Servlet11 映射到 /abc/*
  • Servlet22 映射到 /*
  • Servlet33 映射到 /abc
  • Servlet44 映射到 *.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。

 服务器端路径 /demo4 (转发、包含...)

  1. 相对路径和绝对路径(熟练)

Java中使用的路径,分为两种:绝对路径和相对路径。归根结底,Java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是API在底层帮助我们构建了绝对路径,从而找到资源的!

我们以下面的项目路径来进行举例:

    1. 相对路径

相对路径,根据当前资源路径 与 目标资源路径,寻找相对位置关系,通过 . (当前目录) 和 .. (上一级目录) 访问目标资源;

综上所述,我们发现相对路径总需要分析当前路径与目标路径对应关系,编写规则会根据当前路径不同而不同

    1. 绝对路径

绝对路径是指目录下的绝对位置,直接到达目标位置

带有协议完整路径 (跨网站) http://localhost/day5/hello

以/ 开始路径 (同一个站点内) : /day5/hello

服务器端和客户端对于/ 的区别

客户端访问路径:/day5/hello

服务器内部路径:/hello, 多用于服务器跳转, 页面包含(jsp)

    1. 测试结果

  1. ServletContext(熟练)
    1. ServletContext介绍

ServletContext是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放。request,一个用户可有多个;session,一个用户一个;而servletContext,所有用户共用一个。所以,为了节省空间,提高效率,ServletContext中,要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。

  • WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
  • 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
  • 查看ServletContext API文档,了解ServletContext对象的功能。
    1. ServletContext API

 Object

getAttribute(String name) 
          Returns the servlet container attribute with the given name, or null if there is no attribute by that name.

 String

getContextPath() 
          Returns the context path of the web application.

 String

getInitParameter(String name) 
          Returns a String containing the value of the named context-wide initialization parameter, or null if the parameter does not exist.

 String

getRealPath(String path) 
          Returns a String containing the real path for a given virtual path

 void

setAttribute(String name, Object object) 
          Binds an object to a given attribute name in this servlet context.

 InputStream

getResourceAsStream(String path) 
          Returns the resource located at the named path as an InputStream object.

    1. ServletContext使用
      1. 常规应用:
  • 获取WEB应用的全局初始化参数
  • 通过ServletContext对象实现数据共享

<context-param>
    <param-name>company</param-name>
    <param-value>达内教育</param-value>
</context-param>

ServletContext servletContext = config.getServletContext();
String company = servletContext.getInitParameter("company");
System.out.println("company:"+company);

示例:

统计站点访问次数

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext servletContext = getServletContext();
    Integer visitNums = (Integer)(servletContext.getAttribute("visitNums"));
    visitNums = visitNums == null ? 0 : visitNums;
    servletContext.setAttribute("visitNums",++visitNums);
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write("当前网站访问人次:"+visitNums);
}

      1. 通过ServletContext对象读取资源文件

第一种方法,通过ServletContext.getRealPath()方法;

// 获得到ServletContext对象
ServletContext servletContext = config.getServletContext();

// 获得工程目录web下文件的绝对路径 D:\workspace\idea\servlet-demo1\out\artifacts\servlet_demo1_war_exploded\tx.properties
// getRealPath的参数内容不会被校验,只有真正要用这个路径的时候才知道路径对不对
// String path = servletContext.getRealPath("tx.properties");

String path = servletContext.getRealPath("tx.properties");
System.out.println(path);
try {
    InputStream is = new FileInputStream(path);
    Properties p = new Properties();
    p.load(is);
    String username = p.getProperty("username");
    System.out.println(username);
} catch (Exception e)


    e.printStackTrace();
}

第二种方法,使用servletContext.getResourceAsStream()方法;

//获得工程目录web下文件的流第一个/代表项目的根目录
InputStream is = servletContext.getResourceAsStream("/WEB-INF/tx1.properties");

第三种方法,使用getClass().getClassLoader().getResourceAsStream()方法;

//使用类加载器的方式来读取classpath下的资源文件,好处不依赖与ServletContext,任何类都可以获得classpath下的资源文件,
//不需要再自己指定/WEB-INF/classes
InputStream is = this.getClass().getClassLoader().getResourceAsStream("tx2.properties");

  1. Servlet相关资料(熟练)
    1. 面试题
      1. 单例的Servlet  单例多线程

因为Servlet实例是由Tomcat来创建的,但Tomcat只会创建一个Servlet实例,所以Servlet就是单例的!这与我们自己写的单例模式不太一样。因为这种单例是通过容器tomcat来管理而实现的!

一个实例需要在同一个时间点上处理多个请求!

同步就是安全,但效率太低

Servlet是线程不安全的!

  • 不写属性;
  • 不写可以存储数据的属性!
      1. Servlet的生命周期
  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
  1. 学习目标
  • 了解Servlet概念和JavaWeb的三大组件都包含哪些组件;
  • 创建一个Servlet实现javax.servlet.Servlet接口,并自行验证Servlet的生命周期;
  • 创建一个Servlet继承javax.servlet.http.HttpServlet类,提供一个初始化属性,并在Servlet初始化时打印它;
  • 自己实现统计网址访问人次的功能;
  • 熟练掌握两道面试题


http://www.niftyadmin.cn/n/5797237.html

相关文章

使用Docker启用MySQL8.0.11

目录 一、Docker减小镜像大小的方式 1、基础镜像选择 2、减少镜像层数 3、清理无用文件和缓存 4、优化文件复制&#xff08;COPY和ADD指令&#xff09; 二、Docker镜像多阶段构建 1、什么是dockers镜像多阶段构建 1.1 概念介绍 1.2 构建过程和优势 2、怎样在Dockerfil…

播放端标注叠加方案

方案要求 标注信息能够随着视频数据一起传输&#xff0c;混合在视频数据中数据在解码前&#xff0c;就可以从视频数据中解析出来 传输协议 目前&#xff0c;主流摄像头的数据都是通过RTSP协议进行协商&#xff0c;然后通过RTP传输数据&#xff0c;使用RTCP进行流控。 应用层…

Java中使用四叶天动态代理IP构建ip代理池,实现httpClient和Jsoup代理ip爬虫

在本次爬虫项目中&#xff0c;关于应用IP代理池方面&#xff0c;具体完成以下功能&#xff1a; 从指定API地址提取IP到ip池中&#xff08;一次提取的IP数量可以自定义更改&#xff09; 每次开始爬虫前&#xff08;多条爬虫线程并发执行&#xff09;&#xff0c;从ip池中获取一…

深度学习从入门到精通——图像分割实战DeeplabV3

DeeplabV3算法 参数配置关于数据集的配置训练集参数 数据预处理模块DataSet构建模块测试一下数据集去正则化模型加载模块DeepLABV3 参数配置 关于数据集的配置 parser argparse.ArgumentParser()# Datset Optionsparser.add_argument("--data_root", typestr, defa…

【Java基础面试题029】Java中的hashCode和equals方法之间有什么关系?

回答重点 在Java中&#xff0c;hashCode()和equals方法的关系主要体现在集合类&#xff08;如HashMap、HashSet&#xff09;中。 他俩决定了对象的逻辑相等性和哈希存储方式 equals()方法&#xff1a; 用于判断两个对象是否相等&#xff0c;默认实现是使用比较对象的内存地…

文章发稿平台哪个好用?哪个类型的媒体平台比较好过稿?

在做软文推广的过程中&#xff0c;被拒稿是个常见但又让人头疼的问题。尤其在推广节奏比较紧张的时候&#xff0c;拒稿会导致整个进度被持续拖延&#xff0c;在企业公关、新品推广等环节中会产生较为明显的负面影响。 文章发稿平台哪个好用&#xff1f;哪个类型的文章发稿平台比…

HarmonyOS NEXT 技术实践-基于基础视觉服务的多目标识别

在智能手机、平板和其他智能设备日益智能化的今天&#xff0c;视觉识别技术成为提升用户体验和智能交互的重要手段。HarmonyOS NEXT通过基础视觉服务&#xff08;HMS Core Vision&#xff09;提供了一套强大的视觉识别功能&#xff0c;其中多目标识别作为其关键技术之一&#x…

sh cmake-linux.sh -- --skip-license --prefix = $MY_INSTALL_DIR

本文来自天工AI --------- 命令用于安装CMake的脚本&#xff0c;其中--skip-license参数表示跳过许可协议的显示&#xff0c;--prefix参数指定了CMake的安装目录。$MYINSTALLDIR是一个环境变量&#xff0c;应该在运行命令之前设置为您想要安装CMake的目录。 -------- sh xx…