02 Servlet(上)

本文详细介绍了Servlet的基本概念,包括Servlet的工作流程、主要类和接口、如何创建及配置Servlet,以及Servlet容器如何管理Servlet的生命周期等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Servlet(上)

标签(空格分隔): JavaWeb


认识Servlet

什么是Servlet

Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。

狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

Servlet可完成如下功能:

  • 创建并返回基于客户请求的动态HTML页面。
  • 创建可嵌入到现有HTML 页面中的部分HTML 页面(HTML 片段)。
  • 与其它服务器资源(如数据库或基于Java的应用程序)进行通信。

类和接口

Servlet编程需要使用到javax.servlet 和 javax.servlet.http两个包下面的类和接口,在所有的类和接口中,javax.servlet.servlet 接口最为重要。所有的servlet程序都必须实现该接口或者继承实现了该接口的类。

javax.servlet.ServletConfig;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
javax.servlet.http.Cookie;
javax.servlet.ServletContext;
javax.servlet.GenericServlet;

以上是Servlet的主要类和接口。、

工作流程

首先看到浏览器,servlet也好,jsp也罢,首先我们要明确的是这是一个bs的体系结构,所以说必然有浏览器的,那么浏览器要去访问Tomcat其中的某一个servlet或者说是jsp的时候,必须在ie浏览器当中输入http://........
之类的命令。

敲了回车键之后,浏览器就会向你指定的Servlet容器,也就是Tomcat发送http请求,这个请求会被Tomcat的Web服务器的这个模块接收。web服务器处理之后会转发给Tomcat的容器部分进行处理,他会帮助ie浏览器找到这个请求想要找到的servlet,这时在容器里面的行为,要么是在容器内再向数据库发送操作数据库的命令,要么直接返回结果(html页面)。

当页面被web服务器模块接收到之后,它会将静态页面返回给那个发送请求的那个浏览器,浏览器得到这个结果之后,就会显示出来。

所以可以将结果分成三个部分,第一个部分是浏览器,第二个是Tomcat模块,第三个就是数据库模块。

Servlet容器响应客户请求的过程如下:

  1. Servlet引擎检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4步,否则,执行第2步。
  2. 装载并创建该Servlet的一个实例对象:调用该 Servlet 的构造器
  3. 调用Servlet实例对象的init()方法。
  4. 创建一个用于封装请求的ServletRequest对象和一个代表响应消息的ServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  5. WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

第一个Servlet程序

创建一个Servlet

首先我们不直接创建一个Servlet文件,我们创建一个普通的class类,然后让这个类继承Servlet接口:

package test;

import javax.servlet.*;
import java.io.IOException;

/**
 * Created by japson on 12/17/2017.
 */
public class HelloServlet implements Servlet{
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init....");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("ServletConfig....");
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service....");
    }

    @Override
    public String getServletInfo() {
        System.out.println("getServletInfo....");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destroy....");
    }
}

配置和映射

我们是在src下的test包中创建一个class,那么为了使java类能够被访问,我们要在WEB-INF下的web.xml文件中配置和映射这个Servlet。

 <!--配置和映射Servlet-->
    <servlet>
        <!-- Servlet注册的名字(可以随便起) -->
        <servlet-name>first</servlet-name>
        <!-- Servlet的全类名 -->
        <servlet-class>test.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <!-- 需要和某一个servlet节点的serlvet-name子节点的文本节点一致 -->
        <servlet-name>first</servlet-name>
        <!-- 映射具体的访问路径: / 代表当前 WEB 应用的根目录 -->
        <url-pattern>/firstServlet</url-pattern>
    </servlet-mapping>

第一步:我们通过(自己给Servlet起的)注册名和Servlet的全类名进行注册。这样可以通过全类名找到其物理地址,并于注册名关联起来。

第二步:通过注册名和路径进行映射。url-pattern中为要访问的路径地址。我们就是在浏览器中输入这个路径地址,来获取映射到的注册名,从而找到Servlet的。

注册与运行

Servlet程序必须通过Servlet容器来启动运行,并且储存目录有特殊要求,通需要存储在 WEB应用程序目录\WEB-INF\classes\目录中。

Servlet程序必须在WEB应用程序的web.xml文件中进行注册和映射其访问路径,才可以被Servlet引擎加载和被外界访问。

一个<servlet>元素用于注册一个Servlet,它包含有两个主要的子元素:<servlet-name><servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name><url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

Servlet映射的细节

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

在Servlet映射到的URL中也可以使用通配符,但是只能有两种固定的格式:一种格式是“.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

load-on-startup 参数

load-on-startup参数可以指定Serlvet被创建的时机。若为负数,则在第一次请求时被创建。若为0或正数,则在当前WEB应用被Serlvet容器加载时创建实例,且数组越小越早被创建。

load-on-startup参数配置在 servlet 节点中:

    <servlet>
        <!-- Servlet 注册的名字 -->
        <servlet-name>secondServlet</servlet-name>
        <!-- Servlet 的全类名 -->
        <servlet-class>com.atguigu.javaweb.SecondServlet</servlet-class>
        <!-- 可以指定 Servlet 被创建的时机 -->
        <load-on-startup>2</load-on-startup>
    </servlet>

Servlet生命周期方法

我们说我们创建了一个实现了Servlet接口的一个类,但是我们并没有创建这个类的实例,没有调用这个类的对象。这部分的操作是Servlet容器替我们干了。Servlet容器来帮我们创建Servlet实例,调用构造方法,并且在结束时执行销毁方法。

Servlet容器

  1. 可以来创建 Servlet, 并调用 Servlet 的相关生命周期方法。
  2. JSP, Filter, Listener, Tag …都是运行在Servlet容器中,由Servlet容器来调用其生命周期方法

Servlet生命周期的方法

  1. 构造器: 只被调用一次。只有第一次请求 Servlet 时,创建 Servlet 的实例。调用构造器。这说明 Serlvet 的单实例的。
  2. init 方法: 只被调用一次,在创建好实例后立即被调用。用于初始化当前Servlet。 可以传递ServletConfig参数,这是构造器初始化所不及的。
  3. service: 被多次调用。每次请求都会调用service方法。实际用于响应请求的。
  4. destroy: 只被调用一次。在当前Servlet所在的WEB应用被卸载前调用。 用于释放当前Servlet所占用的资源。

ServletConfig

ServletConfig是一个接口,封装了Serlvet在web.xml中的配置信息(用的不多),并且可以获取ServletContext对象。ServletConfig接口是由Tomcat实现的。

其方法如下:

String getServletName()     //获取当前Servlet在web.xml中配置的名字

String getInitParameter(String name)    //获取当前Servlet指定名称的初始化参数的值

Enumeration getInitParameterNames()     //获取当前Servlet所有初始化参数的名字组成的枚举

ServletContext getServletContext()      //获取代表当前web应用的ServletContext对象

在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。

当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

这样做的好处是:如果将数据库信息、编码方式等配置信息放在web.xml中,如果以后数据库的用户名、密码改变了,则直接很方便地修改web.xml就行了,避免了直接修改源代码的麻烦。

配置Servlet的初始化参数

    <!--配置Servlet-->
    <servlet>
        <!-- Servlet注册的名字(可以随便起) -->
        <servlet-name>first</servlet-name>
        <!-- Servlet的全类名 -->
        <servlet-class>test.HelloServlet</servlet-class>

        <!--配置Servlet的初始化参数,且该节点在servlet节点中,load-on-startup节点前-->
        <init-param>
            <!--参数名-->
            <param-name>user</param-name>
            <!--参数值-->
            <param-value>root</param-value>
        </init-param>

        <init-param>
            <param-name>password</param-name>
            <param-value>1234</param-value>
        </init-param>
    </servlet>

获取初始化参数

下面我们看一下在实现了Servlet接口的类中的init方法中:

    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init....");

        String user = servletConfig.getInitParameter("user");
        System.out.println("uer:" + user);

        Enumeration<String> names = servletConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            System.out.println("name:" + name);
        }
    }

还有一种情况就是我们直接创建一个Servlet,是继承HttpServlet类的,里面有doGet方法和doPost方法。这样我们就要自己获取ServletConfig了:

public class ServletConfigTest extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletConfig config = this.getServletConfig();  //拿到init方法中的ServletConfig对象

        // --获取当前Servlet 在web.xml中配置的名称(用的不多)
         String sName = config.getServletName();
         System.out.println("当前Servlet 在web.xml中配置的名称:"+sName);

        // --获取当前Servlet中配置的初始化参数(只能获取一个)经常用到
        // String value = config.getInitParameter("name2");
        // System.out.println(value);

        // --获取当前Servlet中配置的初始化参数(全部获取)经常用到
         Enumeration enumration = config.getInitParameterNames();
         while(enumration.hasMoreElements()){
         String name = (String) enumration.nextElement();
         String value = config.getInitParameter(name);
         System.out.println(name+":"+value);
         }
    }

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

第6行就是通过this.getServletConfig()方法拿到init方法中的ServletConfig对象,然后获取配置信息。

ServletContext(非常重要)

在ServletConfig中有一个ServletContext getServletContext()方法,用来获取代表当前web应用的ServletContext对象。那么获取到的ServletContext到底是啥?这个非常关键。

Conetxt是上下文,我们以后还有接触很多Context。

什么是ServletContext

Servlet引擎为每个WEB应用程序都创建一个对应的ServletContext对象,ServletContext对象被包含在ServletConfig对象中。

ServletContext对象代表当前 Web 应用。可以认为 SerlvetContext 是当前 WEB 应用的一个大管家。我们可以从 ServletContext 对象中获取到当前 WEB 应用的各个方面的信息。

由于一个WEB应用程序中的所有Servlet都共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。所以,ServletContext对象被称之为 application 对象(Web应用程序对象)。

功能:

  • 获取WEB应用程序的初始化参数
  • 记录日志
  • application域范围的属性
  • 访问资源文件
  • 获取虚拟路径所映射的本地路径
  • WEB应用程序之间的访问
  • ServletContext的其他方法

获取当前 WEB 应用的初始化参数

我们在上面的部分中,通过<servlet></servlet>中的<init-param><、init-param>标签为某一个单独的servlet加配置信息,这种配置信息在其他的Servlet中是无法访问到的。

如果我们使用<context-param>标签(与Servlet标签并列)为整个Web应用配置属性的话,那所有的Servlet就都能访问里面的参数了。例如:可以把数据库的配置信息放在这里。

首先我们要配置当前 WEB 应用的初始化参数

<!-- 配置当前 WEB 应用的初始化参数 -->
<context-param>
    <param-name>driver</param-name>
    <param-value>com.mysql.jdbc.Driver</param-value>
</context-param>

<context-param>
    <param-name>jdbcUrl</param-name>
    <param-value>jdbc.Driver:mysql"///tables</param-value>
</context-param>

获取参数:

//通过ServletConfig对象获取ServletContext对象
ServletContext servletContext = servletConfig.getServletContext();

//获取参数名为driver的 
String driver = servletContext.getInitParameter("driver");
System.out.println("driver:" + driver);

Enumeration<String> names2 = servletContext.getInitParameterNames();
while(names2.hasMoreElements()){
    String name = names2.nextElement();
    System.out.println("-->" + name); 
}

输出:

driver:com.mysql.jdbc.Driver
-->driver
-->jdbcUrl

获取当前 WEB 应用的某一个文件的绝对路径

注意:是在服务器上的绝对路径,而不是部署前的路径。

String realPath = servletContext.getRealPath("/note.txt");
System.out.println(realPath);

获取当前 WEB 应用的名称:

getContextPath()

代码:

String contextPath = servletContext.getContextPath();
System.out.println(contextPath); 

输出格式即为:/应用名

获取当前 WEB 应用的资源文件

我们在JDBC中读取过jdbc.properties资源文件。在非Servlet环境下要读取资源文件时可以采用类加载器加载文件的方式读取资源的方法如下:

ClassLoader classLoader = getClass().getClassLoader();
        InputStream is1 = classLoader.getResourceAsStream("/test/jdbc.properties");
        System.out.println("1. " + is1);

输出结果为:

1. java.io.ByteArrayInputStream@243faa13

那么我们如果通过ServletContext对象的方法来获取呢?

 ServletContext servletContext = servletConfig.getServletContext();
        InputStream is2 = servletContext.getResourceAsStream("/test/jdbc.properties");
        System.out.println("2. " + is2);

输出结果为:

2. null

可见这么写是错的,我们不能够得到正确的路径。那么正确的写法应该是这样的:类加载器从哪个目录加载类,就从哪个目录加载资源,所以此处的路径一定要给一个相对于类加载目录的路径。

我们要知道/WEB-INF/calsses是我们的编译输出目录,在这里同样有我们自动生成的jdbc.properties文件。因此我们应该这么些:

ServletContext servletContext = servletConfig.getServletContext();
        InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/test/jdbc.properties");
        System.out.println("2. " + is2);

输出结果为:

2. java.io.ByteArrayInputStream@32532d8

与attribute相关的方法

这个很重要,但是我们要与后面的内容对比来讲。

Servlet(上)

标签(空格分隔): JavaWeb


认识Servlet

什么是Servlet

Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。

狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

Servlet可完成如下功能:

  • 创建并返回基于客户请求的动态HTML页面。
  • 创建可嵌入到现有HTML 页面中的部分HTML 页面(HTML 片段)。
  • 与其它服务器资源(如数据库或基于Java的应用程序)进行通信。

类和接口

Servlet编程需要使用到javax.servlet 和 javax.servlet.http两个包下面的类和接口,在所有的类和接口中,javax.servlet.servlet 接口最为重要。所有的servlet程序都必须实现该接口或者继承实现了该接口的类。

javax.servlet.ServletConfig;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
javax.servlet.http.Cookie;
javax.servlet.ServletContext;
javax.servlet.GenericServlet;

以上是Servlet的主要类和接口。、

工作流程

首先看到浏览器,servlet也好,jsp也罢,首先我们要明确的是这是一个bs的体系结构,所以说必然有浏览器的,那么浏览器要去访问Tomcat其中的某一个servlet或者说是jsp的时候,必须在ie浏览器当中输入http://........
之类的命令。

敲了回车键之后,浏览器就会向你指定的Servlet容器,也就是Tomcat发送http请求,这个请求会被Tomcat的Web服务器的这个模块接收。web服务器处理之后会转发给Tomcat的容器部分进行处理,他会帮助ie浏览器找到这个请求想要找到的servlet,这时在容器里面的行为,要么是在容器内再向数据库发送操作数据库的命令,要么直接返回结果(html页面)。

当页面被web服务器模块接收到之后,它会将静态页面返回给那个发送请求的那个浏览器,浏览器得到这个结果之后,就会显示出来。

所以可以将结果分成三个部分,第一个部分是浏览器,第二个是Tomcat模块,第三个就是数据库模块。

Servlet容器响应客户请求的过程如下:

  1. Servlet引擎检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4步,否则,执行第2步。
  2. 装载并创建该Servlet的一个实例对象:调用该 Servlet 的构造器
  3. 调用Servlet实例对象的init()方法。
  4. 创建一个用于封装请求的ServletRequest对象和一个代表响应消息的ServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  5. WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

第一个Servlet程序

创建一个Servlet

首先我们不直接创建一个Servlet文件,我们创建一个普通的class类,然后让这个类继承Servlet接口:

package test;

import javax.servlet.*;
import java.io.IOException;

/**
 * Created by japson on 12/17/2017.
 */
public class HelloServlet implements Servlet{
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init....");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("ServletConfig....");
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service....");
    }

    @Override
    public String getServletInfo() {
        System.out.println("getServletInfo....");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("destroy....");
    }
}

配置和映射

我们是在src下的test包中创建一个class,那么为了使java类能够被访问,我们要在WEB-INF下的web.xml文件中配置和映射这个Servlet。

 <!--配置和映射Servlet-->
    <servlet>
        <!-- Servlet注册的名字(可以随便起) -->
        <servlet-name>first</servlet-name>
        <!-- Servlet的全类名 -->
        <servlet-class>test.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <!-- 需要和某一个servlet节点的serlvet-name子节点的文本节点一致 -->
        <servlet-name>first</servlet-name>
        <!-- 映射具体的访问路径: / 代表当前 WEB 应用的根目录 -->
        <url-pattern>/firstServlet</url-pattern>
    </servlet-mapping>

第一步:我们通过(自己给Servlet起的)注册名和Servlet的全类名进行注册。这样可以通过全类名找到其物理地址,并于注册名关联起来。

第二步:通过注册名和路径进行映射。url-pattern中为要访问的路径地址。我们就是在浏览器中输入这个路径地址,来获取映射到的注册名,从而找到Servlet的。

注册与运行

Servlet程序必须通过Servlet容器来启动运行,并且储存目录有特殊要求,通需要存储在 WEB应用程序目录\WEB-INF\classes\目录中。

Servlet程序必须在WEB应用程序的web.xml文件中进行注册和映射其访问路径,才可以被Servlet引擎加载和被外界访问。

一个<servlet>元素用于注册一个Servlet,它包含有两个主要的子元素:<servlet-name><servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name><url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

Servlet映射的细节

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

在Servlet映射到的URL中也可以使用通配符,但是只能有两种固定的格式:一种格式是“.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

load-on-startup 参数

load-on-startup参数可以指定Serlvet被创建的时机。若为负数,则在第一次请求时被创建。若为0或正数,则在当前WEB应用被Serlvet容器加载时创建实例,且数组越小越早被创建。

load-on-startup参数配置在 servlet 节点中:

    <servlet>
        <!-- Servlet 注册的名字 -->
        <servlet-name>secondServlet</servlet-name>
        <!-- Servlet 的全类名 -->
        <servlet-class>com.atguigu.javaweb.SecondServlet</servlet-class>
        <!-- 可以指定 Servlet 被创建的时机 -->
        <load-on-startup>2</load-on-startup>
    </servlet>

Servlet生命周期方法

我们说我们创建了一个实现了Servlet接口的一个类,但是我们并没有创建这个类的实例,没有调用这个类的对象。这部分的操作是Servlet容器替我们干了。Servlet容器来帮我们创建Servlet实例,调用构造方法,并且在结束时执行销毁方法。

Servlet容器

  1. 可以来创建 Servlet, 并调用 Servlet 的相关生命周期方法。
  2. JSP, Filter, Listener, Tag …都是运行在Servlet容器中,由Servlet容器来调用其生命周期方法

Servlet生命周期的方法

  1. 构造器: 只被调用一次。只有第一次请求 Servlet 时,创建 Servlet 的实例。调用构造器。这说明 Serlvet 的单实例的。
  2. init 方法: 只被调用一次,在创建好实例后立即被调用。用于初始化当前Servlet。 可以传递ServletConfig参数,这是构造器初始化所不及的。
  3. service: 被多次调用。每次请求都会调用service方法。实际用于响应请求的。
  4. destroy: 只被调用一次。在当前Servlet所在的WEB应用被卸载前调用。 用于释放当前Servlet所占用的资源。

ServletConfig

ServletConfig是一个接口,封装了Serlvet在web.xml中的配置信息(用的不多),并且可以获取ServletContext对象。ServletConfig接口是由Tomcat实现的。

其方法如下:

String getServletName()     //获取当前Servlet在web.xml中配置的名字

String getInitParameter(String name)    //获取当前Servlet指定名称的初始化参数的值

Enumeration getInitParameterNames()     //获取当前Servlet所有初始化参数的名字组成的枚举

ServletContext getServletContext()      //获取代表当前web应用的ServletContext对象

在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。

当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

这样做的好处是:如果将数据库信息、编码方式等配置信息放在web.xml中,如果以后数据库的用户名、密码改变了,则直接很方便地修改web.xml就行了,避免了直接修改源代码的麻烦。

配置Servlet的初始化参数

    <!--配置Servlet-->
    <servlet>
        <!-- Servlet注册的名字(可以随便起) -->
        <servlet-name>first</servlet-name>
        <!-- Servlet的全类名 -->
        <servlet-class>test.HelloServlet</servlet-class>

        <!--配置Servlet的初始化参数,且该节点在servlet节点中,load-on-startup节点前-->
        <init-param>
            <!--参数名-->
            <param-name>user</param-name>
            <!--参数值-->
            <param-value>root</param-value>
        </init-param>

        <init-param>
            <param-name>password</param-name>
            <param-value>1234</param-value>
        </init-param>
    </servlet>

获取初始化参数

下面我们看一下在实现了Servlet接口的类中的init方法中:

    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init....");

        String user = servletConfig.getInitParameter("user");
        System.out.println("uer:" + user);

        Enumeration<String> names = servletConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            System.out.println("name:" + name);
        }
    }

还有一种情况就是我们直接创建一个Servlet,是继承HttpServlet类的,里面有doGet方法和doPost方法。这样我们就要自己获取ServletConfig了:

public class ServletConfigTest extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletConfig config = this.getServletConfig();  //拿到init方法中的ServletConfig对象

        // --获取当前Servlet 在web.xml中配置的名称(用的不多)
         String sName = config.getServletName();
         System.out.println("当前Servlet 在web.xml中配置的名称:"+sName);

        // --获取当前Servlet中配置的初始化参数(只能获取一个)经常用到
        // String value = config.getInitParameter("name2");
        // System.out.println(value);

        // --获取当前Servlet中配置的初始化参数(全部获取)经常用到
         Enumeration enumration = config.getInitParameterNames();
         while(enumration.hasMoreElements()){
         String name = (String) enumration.nextElement();
         String value = config.getInitParameter(name);
         System.out.println(name+":"+value);
         }
    }

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

第6行就是通过this.getServletConfig()方法拿到init方法中的ServletConfig对象,然后获取配置信息。

ServletContext(非常重要)

在ServletConfig中有一个ServletContext getServletContext()方法,用来获取代表当前web应用的ServletContext对象。那么获取到的ServletContext到底是啥?这个非常关键。

Conetxt是上下文,我们以后还有接触很多Context。

什么是ServletContext

Servlet引擎为每个WEB应用程序都创建一个对应的ServletContext对象,ServletContext对象被包含在ServletConfig对象中。

ServletContext对象代表当前 Web 应用。可以认为 SerlvetContext 是当前 WEB 应用的一个大管家。我们可以从 ServletContext 对象中获取到当前 WEB 应用的各个方面的信息。

由于一个WEB应用程序中的所有Servlet都共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。所以,ServletContext对象被称之为 application 对象(Web应用程序对象)。

功能:

  • 获取WEB应用程序的初始化参数
  • 记录日志
  • application域范围的属性
  • 访问资源文件
  • 获取虚拟路径所映射的本地路径
  • WEB应用程序之间的访问
  • ServletContext的其他方法

获取当前 WEB 应用的初始化参数

我们在上面的部分中,通过<servlet></servlet>中的<init-param><、init-param>标签为某一个单独的servlet加配置信息,这种配置信息在其他的Servlet中是无法访问到的。

如果我们使用<context-param>标签(与Servlet标签并列)为整个Web应用配置属性的话,那所有的Servlet就都能访问里面的参数了。例如:可以把数据库的配置信息放在这里。

首先我们要配置当前 WEB 应用的初始化参数

<!-- 配置当前 WEB 应用的初始化参数 -->
<context-param>
    <param-name>driver</param-name>
    <param-value>com.mysql.jdbc.Driver</param-value>
</context-param>

<context-param>
    <param-name>jdbcUrl</param-name>
    <param-value>jdbc.Driver:mysql"///tables</param-value>
</context-param>

获取参数:

//通过ServletConfig对象获取ServletContext对象
ServletContext servletContext = servletConfig.getServletContext();

//获取参数名为driver的 
String driver = servletContext.getInitParameter("driver");
System.out.println("driver:" + driver);

Enumeration<String> names2 = servletContext.getInitParameterNames();
while(names2.hasMoreElements()){
    String name = names2.nextElement();
    System.out.println("-->" + name); 
}

输出:

driver:com.mysql.jdbc.Driver
-->driver
-->jdbcUrl

获取当前 WEB 应用的某一个文件的绝对路径

注意:是在服务器上的绝对路径,而不是部署前的路径。

String realPath = servletContext.getRealPath("/note.txt");
System.out.println(realPath);

获取当前 WEB 应用的名称:

getContextPath()

代码:

String contextPath = servletContext.getContextPath();
System.out.println(contextPath); 

输出格式即为:/应用名

获取当前 WEB 应用的资源文件

我们在JDBC中读取过jdbc.properties资源文件。在非Servlet环境下要读取资源文件时可以采用类加载器加载文件的方式读取资源的方法如下:

ClassLoader classLoader = getClass().getClassLoader();
        InputStream is1 = classLoader.getResourceAsStream("/test/jdbc.properties");
        System.out.println("1. " + is1);

输出结果为:

1. java.io.ByteArrayInputStream@243faa13

那么我们如果通过ServletContext对象的方法来获取呢?

 ServletContext servletContext = servletConfig.getServletContext();
        InputStream is2 = servletContext.getResourceAsStream("/test/jdbc.properties");
        System.out.println("2. " + is2);

输出结果为:

2. null

可见这么写是错的,我们不能够得到正确的路径。那么正确的写法应该是这样的:类加载器从哪个目录加载类,就从哪个目录加载资源,所以此处的路径一定要给一个相对于类加载目录的路径。

我们要知道/WEB-INF/calsses是我们的编译输出目录,在这里同样有我们自动生成的jdbc.properties文件。因此我们应该这么些:

ServletContext servletContext = servletConfig.getServletContext();
        InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/test/jdbc.properties");
        System.out.println("2. " + is2);

输出结果为:

2. java.io.ByteArrayInputStream@32532d8

与attribute相关的方法

这个很重要,但是我们要与后面的内容对比来讲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值