第二章:Servlet基础
OVERVIEW
随着Web应用业务需求的增多,动态Web资源的开发变得越来越重要。很多公司都提供了开发动态Web资源的相关技术,包括ASP、PHP、JSP、Servlet等,其中JSP、Servlet技术由sun公司提供。
一、Servlet介绍
1.Servlet概念
Servlet是指使用Java语言编写的运行在服务器端的程序
。
狭义的Servlet是指Java语言实现的一个接口
,广义的Servlet是指任何实现了这个Servlet接口的类
,一般理解为后者。
Servlet主要用于处理客户端传来的HTTP请求(处理doGet()
、doPost()
等请求方法),并返回一个响应。
2.Servlet应用程序体系结构
Servlet由Servlet容器(即提供了Servlet功能的服务器,如Tomcat)提供,Servlet容器将Servlet动态的加载到服务器上。
与HTTP协议相关的Servlet使用HTTP请求和HTTP响应与客户端进行交互,故Servlet容器支持所有HTTP协议的请求和响应。
Servlet应用程序的体系结构如下:
对于Servlet应用程序运行全流程的分析:
- 客户端发出Servlet请求,请求首先被HTTP服务器(如Apache)接收
- HTTP服务器对静态HTML页面进行解析,对于Servlet的请求转交给Servlet容器处理
- Servlet容器根据web.xml文件中的映射关系,调用相应的Servlet,被调用的Servlet将处理结果返回Servlet容器
- 处理结果由Servlet容器经过HTTP服务器最终返回客户端
3.Servlet技术特点
- 方便:Servlet提供了大量实用工具例程,处理很难完成的HTML表单数据、读取和设置HTTP头,以及处理Cookie和跟踪会话等
- 跨平台:Servlet用Java编写,可在不同操作系统平台和不同应用服务器平台下运行
- 灵活性&可扩展性:采用Servlet开发的Web应用程序,由于Java类的继承性及构造函数等特点,使得应用灵活、可随意扩展
二、Servlet开发入门
1.Servlet接口及其实现类
(1)Servlet接口:
针对Servlet技术的开发,sun公司提供了一系列接口和类,其中最重要的接口就是javax.servlet.Servlet。Servlet接口中定义了5个抽象方法:
Servlet接口定义抽象方法 | 功能描述 |
---|---|
void init(ServletConfig config) | 容器在创建Servlet对象后,就会调用此方法。Servlet容器通过ServletConfig类型的参数向Servlet传递初始化信息。 |
ServletConfig getServletConfig() | 获取Servlet对象的配置信息,返回Servlet的ServletConfig对象 |
String getServletInfo() | 返回一个字符串包含Servlet的信息(作者、版本等) |
void service(ServletRequest request, ServletResponse response) | 负责响应用户请求,通过ServletRequest对象得到客户端的相关信息和请求信息,通过调用ServletResponse对象的方法设置响应信息 |
void destroy() | 释放Servlet对象占用的资源 |
注意:以上提及的Servlet容器都指的是web服务器(如Tomcat)
(2)Servlet实现类:
针对Servlet接口,sun公司提供了两个默认的接口实现类GenericServlet
和HttpServlet
。
GenericServlet是一个抽象类为Servlet接口提供了部分实现,但并没有实现HTTP请求处理;HttpServlet作为子类继承了GenericServlet的所用方法,并且为HTTP请求中的POST\GET等类型提供了具体操作方法。
通常情况下编写的Servlet类都继承自HttpServlet,在开发中使用的具体Servlet对象就是HttpServlet对象
以下为HttpServlet对象常用的方法及其说明:
方法声明 | 功能描述 |
---|---|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) | 处理GET类型的HTTP请求 |
protected void doPost(HttpServletRequest req, HttpServletResponse resp) | 处理POST类型的HTTP请求 |
protected void doPut(HttpServletRequest req, HttpServletResponse resp) | 处理PUT类型的HTTP请求 |
2.实现第一个Servlet程序
以下分步骤实现一个Servlet程序,并演示其使用。
(1)创建Servlet程序:
在任意某个目录下编写一个Servlet,这里位置以C盘根目录为例编写。
特别注意:package包名不可命名为servlet
package test;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
public class HelloServlet extends GenericServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
//得到输出流对象PrinterWriter,Servlet使用输出流来产生响应
PrintWriter out = response.getWriter();
//使用输出流对象PrinterWriter向客户端发送字符数据
out.println("HelloWorld Servlet!");
}
}
直接实现Servlet接口来编写Servlet程序很不方便,可以通过继承Servlet接口的实现类
javax.servlet.GenericServlet
来实现。
(2)引入Servlet的JAR包:
由于Servlet程序是一个JavaEE程序而不是JavaSE程序,因此所有的JAR文件都需要自己手动的加到CLASSPATH环境变量中。
在Tomcat安装目录下的lib目录里包含了许多与Tomcat服务器相关的JAR文件,其中servlet-api.jar
就是与Servlet相关的JAR文件。
打开命令行窗口通过set classpath
命令将servlet-api.jar
文件所在目录添加到CLASSPATH环境变量中。
(3)编译Servlet程序:
注:编译成功的标志是出现一个与Servlet程序名同名的class文件
(4)将编译后的class文件添加到服务器:
注意:关于Webapp的文件结构必须要十分规范,否则将导致无法访问网页资源404
在Tomcat的webapps下创建目录myFirstWebapp
为Web应用的名称。
在myFirstWebapp
中创建\WEB-INF\classes目录,并将之前编译产生的.class
文件及其所在package
拷贝到classes
目录下,如下所示:
(5)创建web.xml文件:
进入WEB-INF目录中,编写一个web.xml
文件,如下所示:
注意:
web.xml
文件的名称不可随意修改或自定义
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<!-- 元素Servlet用于注册Servlet -->
<servlet>
<!-- 子元素servlet-name用于命名Servlet -->
<servlet-name>myFirstServlet</servlet-name>
<!-- 子元素servlet-class用于指定Servlet完整类名 -->
<servlet-class>test.HelloServlet</servlet-class>
</servlet>
<!-- 元素servlet-mapping用于映射Servlet对外访问的虚拟路径 -->
<servlet-mapping>
<!-- servlet-mapping与servlet中的子元素servlet-name名称相同 -->
<servlet-name>myFirstServlet</servlet-name>
<!-- 设置访问地址,/代表web应用程序的根目录 -->
<url-pattern>/def</url-pattern>
</servlet-mapping>
</web-app>
到此Servlet程序全部部署完毕!
步骤诠释:步骤4、5的实际目的是将Servlet程序部署到服务器上,步骤6访问服务器并调用Servlet程序作出响应
(6)运行服务器并查看结果:
双击Tomcat安装目录的bin子目录下的startup.bat
文件以启动Tomcat服务器。
在谷歌浏览器(任意浏览器)中输入设置的地址进行页面的访问,此处访问地址为http://localhost:8080/myFirstWebapp/def
访问成功!
3.Servlet的生命周期
按照功能不同大致可以将Servlet的生命周期分为3个阶段,分别如下所示:
补充:在web.xml配置中添加
<load-on-startup>
元素可以实现Tomcat启动自动加载Servlet程序。设置的值必须是一个整数:
- 如果设置的值为一个负数 or 没有设定元素,Servlet容器将在客户端首次请求这个Servlet时加载它;
- 如果是设置的数值为 0 or 正数,Servlet容器将在web应用启动时加载并初始化Servlet。并且
<load-on-startup>
设置的值越小,对应的Servlet就越会被优先加载。
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>myFirstServlet</servlet-name>
<servlet-class>test.HelloWorldServlet</servlet-class>
<!-- 设置Servlet在web应用启动时初始化 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myFirstServlet</servlet-name>
<url-pattern>/def</url-pattern>
</servlet-mapping>
</web-app>
三、Servlet开发之HttpServlet类
1.HttpServlet类介绍
注意:在实际开发中,实现Servlet接口更多选择的是继承
HttpServlet
类而不是GenericServlet
类
大多数Web应用都是通过HTTP协议和客户端进行交互,因此在Servlet接口中提供了一个抽象类javax.servlet.http.HttpServlet
,它是GenericServlet的子类,专门用于创建应用与HTTP协议的Servlet。
分析HttpServlet源码,发现其主要的两大功能:
- 根据用户请求方式的不同,定义相应的
doXXX()
方法处理用户请求(重点) - 通过
service()
方法将HTTP请求和响应分别强转为HttpServletRequest和HttpServletResponse类型的对象
注意:由于HttpServlet类在重写的
service()
方法中为每一种HTTP请求方式都定义了对应的doXXX()
方法,因此当定义的类继承HttpServlet类之后只需要根据请求方式,重写对应的doXXX()
方法即可而不需要重写service()
方法
以下程序为演示HttpServlet类根据用户请求方式的不同,以不同的doXXX()
方法处理用户请求:
package c3p1;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class RequestMethodServlet extends HttpServlet{
//重写HttpServlet类中的doGet方法
public void doGet(HttpServletRequest request, HttpServletResponse response ) throws IOException {
PrintWriter out = response.getWriter();
out.write("this is doGet method");
}
//重写HttpServlet类中的doPost方法
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
out.write("this is doPost method");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>RequestMethodServlet</servlet-name>
<servlet-class>c3p1.RequestMethodServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestMethodServlet</servlet-name>
<url-pattern>/1234</url-pattern>
</servlet-mapping>
</web-app>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RequestMethodServlet</title>
</head>
<body>
<form action="/chapter03_servlet/1234" method="get"><br />
<input type="submit" value="form表单以get方式提交">
</form>
<form action="/chapter03_servlet/1234" method="post"><br />
<input type="submit" value="form表单以post方式提交">
</form>
<br />
<a href="/chapter03_servlet/1234">超链接形式以get方式访问</a>
</body>
</html>
启动服务器后,在谷歌浏览其中输入url地址访问form.html
页面,并在页面中进行访问测试结果如下:
2.使用eclipse开发Servlet
在实现第一个Servlet程序时没有借助任何开发工具,开发步骤从创建Servlet程序、引入Servlet的JAR包、编译Servlet程序、将class文件添加到服务器、创建web.xml文件总共包括了5个步骤,开发步骤十分繁琐。
在实际开发中都会使用eclipse工具完成Servlet的开发,eclipse会自动编译Servlet、创建web.xml文件信息、完成Servlet虚拟路径映射。
eclipse开发工具开发中所替代的繁琐工作:
- 自动将src目录下的Servlet文件编译成class文件,存放到classes目录下
- 创建Servlet时自动将Servlet的相关配置文件添加到web.xml中,完成虚拟路径映射
- 在本地编辑的Webapp文件更加便捷的与tomcat服务器上Synchronize同步,部署更加便捷
3.实现Servlet虚拟路径的映射
在web.xml文件中,一个<servlet-mapping>
元素用于映射一个Servlet的对外访问路径,该路径也称为虚拟路径。
创建好的Servlet程序只有映射成虚拟路径,客户端才能对其进行访问。以下介绍Servlet映射中的相关问题:
(1)Servlet的多重映射:
Servlet的多重映射指的是一个Servlet可以被映射成多个虚拟路径,客户端可以通过多个路径实现对同一个Servlet访问。
Servlet多重映射的实现有如下两种方式:
- 配置多个
<servlet-mapping>
元素 - 在
<servlet-mapping>
元素下配置多个<url-pattern>
子元素
(2)Servlet映射路径中使用通配符:
在实际开发中有时希望某个目录下的所有路径都可以访问同一个Servlet,这时可以在Servlet映射的路径中使用通配符*
。
通配符的格式有两种如下所示:
case1:格式为*.扩展名
例如,*.do
表示匹配以.do
结尾的所有url地址
case2:格式为/*
例如,/abc/*
表示匹配以/abc
开始的所有url地址
注意:这两种通配符的格式不能混合使用,如果请求的url地址能够匹配到多个虚拟路径,那么tomcat服务器将采取最具体匹配原则查找与请求url最接近的虚拟映射路径。
(3)缺省Servlet:
如果某个Servlet的映射路径仅仅是一个正斜杠/
,那么这个Servlet就是当前Web应用缺省的Servlet。
Servlet服务器在接收到访问请求时,如果在web.xml文件中都找不到匹配的<servlet-mapping>
元素的url,就会将访问请求交给缺省的Servlet处理,即缺省的Servlet用于处理其他Servlet都不处理的访问请求。
以下程序演示缺省Servlet的使用:
package pkg;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServlet;
public class Servlet01 extends HttpServlet{
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
out.println("You have accessed the first Servlet application");
}
}
package pkg;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Default_servlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
out.println("You have accessed the default Servlet application");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>Servlet01</servlet-name>
<servlet-class>pkg.Servlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/123</url-pattern>
</servlet-mapping>
<!-- 缺省Servlet -->
<servlet>
<servlet-name>Default_servlet</servlet-name>
<servlet-class>pkg.Default_servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Default_servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
总结:可以看出在当输入url地址进行访问其他Servlet都不处理时,访问请求由缺省Servlet进行了处理
四、ServletConfig和ServletContext
1.ServletConfig接口
在Servlet运行期间经常需要一些辅助信息,如:文件使用的编码、使用Servlet程序的共享。这些信息可以在web.xml文件中使用一个或多个<init-param>
元素进行配置。
当tomcat初始化一个servlet时,会将该Servlet的配置信息封装到一个ServletConfig对象中,通过调用init(ServletConfig config)
方法将ServletConfig对象传递给Servlet。
ServletConfig定义了一系列获取配置信息的方法,如下表所示:
配置获取方法 | 功能描述 |
---|---|
String getInitParameter(String name) | 根据初始化参数名返回对应的初始化参数值 |
Enumeration getInitParameterNames() | 返回一个Enumeration对象,其中包含了所有的初始化参数名 |
ServletContext getServletContext() | 返回一个代表当前Web应用的ServletContext对象 |
String getServletName() | 返回Servlet的名字,即web.xml中<servlet-name> 元素的值 |
以下程序演示String getInitParameter(String name)
方法的使用:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>Servlet01</servlet-name>
<servlet-class>pkg.Servlet01</servlet-class>
<!-- init-param节点表示要设置的参数 -->
<init-param>
<param-name>author</param-name>
<param-value>HelloWorld999</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/123</url-pattern>
</servlet-mapping>
</web-app>
package pkg;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Servlet01 extends HttpServlet{
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取ServletContext对象
ServletConfig config = this.getServletConfig();
// 获取参数名对应的参数值
String param = config.getInitParameter("author");
// 输出获取的参数值
PrintWriter out = response.getWriter();
out.println("author:" + param);
}
}
2.ServletContext接口
当Servlet容器启动时,会为每一个Web应用创建唯一的ServletContext对象代表当前应用。
ServletContext不仅封装了Web应用的所用信息,还实现了多个Servlet之间数据的共享,其不同作用如下所示:
(1)获取Web应用程序的初始化参数
在web.xml文件中,不仅可以配置Servlet的初始信息,还可以配合context-param
元素配置整个Web应用的初始信息,如下程序所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<context-param>
<param-name>blogger</param-name>
<param-value>HelloWorld999</param-value>
</context-param>
<context-param>
<param-name>chapter</param-name>
<param-value>JavaWeb_Servlet</param-value>
</context-param>
<context-param>
<param-name>reference</param-name>
<param-value>JavaWeb_itcast</param-value>
</context-param>
<context-param>
<param-name>date</param-name>
<param-value>01-9-5</param-value>
</context-param>
<context-param>
<param-name>weather</param-name>
<param-value>rainy</param-value>
</context-param>
<servlet>
<servlet-name>Servlet01</servlet-name>
<servlet-class>pkg.Servlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/123</url-pattern>
</servlet-mapping>
</web-app>
获取Web应用的初始化参数信息,可以使用ServletContext接口中定义的getInitParameterNames()
和getInitParameter(String name)
方法来分别获取参数名和参数值,具体使用如下所示:
package pkg;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Servlet01 extends HttpServlet{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 获取包含所有参数名的Enumeration对象
Enumeration<String> paramNames = context.getInitParameterNames();
PrintWriter out = response.getWriter();
out.println("all the paramName and paramValue are following:<br />");
//遍历所有的参数名,获取相应的参数值并打印出来
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = context.getInitParameter(name);
out.println(name + " : " + value);
out.println("<br />");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
this.doPost(request, response);
}
}
疑问:ServletContext获取初始化参数的顺序是什么样的,为什么输出的结果并没按xml文档中的先后进行输出?
(2)实现多个Servlet对象共享数据
由于一个Web应用中的所有Servlet共享一个ServletContext对象,因此ServletContext对象的属性域可以为Web应用的所有Servlet访问。
在ServletContext接口中定义了分别用于增加、删除、设置ServletContext属性域的4个方法如下:
数据操纵方法 | 功能描述 |
---|---|
Enumeration getAttributeNames() | 返回一个Enumeration对象,包含存放在ServletContext中的所有域属性名 |
Object getAttribute(String name) | 根据指定的参数名返回一个与之匹配的属性域值 |
void removeAttribute(String name) | 根据指定的域属性名,从ServletContext中删除匹配的域属性 |
void setAttribute(String name, Object obj) | 设置ServletContext的域属性值,name为域属性名,obj为域属性值 |
以下程序演示ServletContext对象在Servlet之间的数据共享:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>Servlet01</servlet-name>
<servlet-class>pkg.Servlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/123</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Servlet02</servlet-name>
<servlet-class>pkg.Servlet02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet02</servlet-name>
<url-pattern>/1234</url-pattern>
</servlet-mapping>
</web-app>
package pkg;
import java.io.IOException;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Servlet01 extends HttpServlet{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 通过setAttribute()方法设置data属性值
context.setAttribute("data", "this servlet share the data!");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
this.doPost(request, response);
}
}
package pkg;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Servlet02 extends HttpServlet{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 通过getAttribute()方法获取属性值
String data = (String) context.getAttribute("data");
PrintWriter out =response.getWriter();
out.println(data);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
this.doPost(request, response);
}
}
在未访问servlet01(即为设置数据之前)直接访问servlet02(尝试获取数据)结果:
在访问servlet01(即为设置数据之后)之后再次访问servlet02(尝试获取数据)结果:
注意:如果不访问servlet01则数据不会被设置,那么servlet02也就查询不到数据,返回为null
(3)读取Web应用下的资源文件
有时需要读取Web应用中的一些资源文件,如配置文件、图片信息等。在ServletContext接口中定义了一些读取Web资源的方法:
这些方法依靠Servlet容器实现,Servlet容器根据资源文件相对于Web应用的路劲,返回关联资源文件的IO流、文件系统的绝对路径等。
Web资源读取 | 说明 |
---|---|
Set getResourcePath(String path) | 返回一个Set集合包含资源目录中,子目录和文件的路径名称 |
String getRealPath(String path) | 返回资源文件在服务器文件系统上的真实路径(绝对路径),否则返回null |
URL getResource(String path) | 返回映射到某个资源文件的URL对象 |
InputStream getResourceAsStream(String path) | 返回映射到某个资源文件的InputStream对象 |
以下程序演示使用ServletContext对象读取Web资源文件:
title = resource_obtain
author = HelloWorld
date = 21-09-05
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>Resource_obtain</servlet-name>
<servlet-class>pkg.Resource_obtain</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resource_obtain</servlet-name>
<url-pattern>/123</url-pattern>
</servlet-mapping>
</web-app>
package pkg;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Resource_obtain extends HttpServlet{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
// 获取ServletContext对象
ServletContext context = this.getServletContext();
// 获取相对路径中的输入流对象
InputStream inputStream = context.getResourceAsStream("/WEB-INF/classes/Resource.properties");
Properties pros = new Properties();
pros.load(inputStream);
//开始输出获取资源
PrintWriter out = response.getWriter();
out.println("title:" + pros.getProperty("title") + "<br />");
out.println("author:" + pros.getProperty("author") + "<br />");
out.println("date:" + pros.getProperty("date") + "<br />");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
this.doPost(request, response);
}
}
总结:resource.properties资源文件内容被ServletContext的getResourceAsStream方法读取