Servlet接口的实现类,路径配置映射,ServletConfig对象,ServletContext对象及web工程中文件的读取

时间:2023-11-09 18:55:32

一,Servlet接口实现类:sun公司为Servlet接口定义了两个默认的实现类,分别为:GenericServlet和HttpServlet。

HttpServlet:指能够处理HTTP请求的servlet,它在原有的Servlet接口上添加了一与HTTP协议处理的方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。

HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如果为GET请求,则调用HttpServlet的doGet方法,如果为POST请求,则调用doPost方法。因此开发人员在编写Servlet时,通常只需要覆写doGet方法或者doPost方法,而不要去覆写service方法。

在我们自己写的类去继承HttpServlet时应该注意以下几点:

1)Servlet初始化时覆盖init(),无需覆盖 init(config);

2)根据Http请求的方式,覆盖相应的doGet或者doPost方法,无需覆盖Service方法

3)当doGet和doPost方法代码逻辑相同时,可以相互调用,简化编程。

init() 和 init(ServletConfig) 关系

init(ServletConfig) 是Servlet生命周期的方法 ,GenericServlet内部 覆盖了 init(ServletConfig) ,在有参数init方法中调用无参数init ,建议 自定义Servlet只需要覆盖无参数 init 就可以了

配置 Servlet自动加载:如果在<servlet>元素中配置了一个<load-on-startup>元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。

举例:

    <servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

二,配置Servlet路径映射配置:

由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用元素和元素完成。

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

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

例如:

<web-app>
<servlet>
<servlet-name>AnyName</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>/demo/hello.html</url-pattern>
</servlet-mapping>
</web-app>

其中,URL-Pattern的三种配置方式

1、完全路径匹配:以/开始,不能包含通配符* 例如: /hello /init

2、目录匹配:以/开始, /*结尾 例如: /* /aa/* /aaa/bbb/*

3、扩展名匹配:不能以/开始,以开始 例如: .do *.action

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

注意:

1)同一个Servlet可以被映射到多个URL上,即多个元素的子元素的设置值可以是同一个Servlet的注册名。

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

例如:

<servlet-mapping>
<servlet-name>
AnyName
</servlet-name>
<url-pattern>
*.do
</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>
AnyName
</servlet-name>
<url-pattern>
/action/*
</url-pattern>
</servlet-mapping>

Web系统中的相对路径和绝对路径

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

例如:

在WebRoot下 新建 1.html

在WebRoot/aa 下新建 2.html

在1.html 和 2.html 分别通过超链接访问HelloServlet

1.html
<h1>相对路径</h1>
<a href="./hello">HelloServlet</a>
<a href="hello">HelloServlet</a>
<h1>绝对路径</h1>
<a href="http://localhost/day/hello">HelloServlet</a>
<a href="/day/hello">HelloServlet</a> 2.html
<h1>相对路径</h1>
<a href="../hello">HelloServlet</a>
<h1>绝对路径</h1>
<a href="http://localhost/day/hello">HelloServlet</a>
<a href="/day/hello">HelloServlet</a>
</body>

1.html 访问 HelloServlet

当前路径 http://localhost/day/1.html

目标路径 http://localhost/day/hello

位于同一个目录中 ./hello 、hello ===== 替换当前路径最后一个资源

2.html 访问 HelloServlet

当前路径 http://localhost/day/aaa/2.html

目标路径 http://localhost/day/hello

上一级目录中 ../hello ===== 替换上一级目录资源

相对路径,总需要分析当前路径与目标路径对应关系,编写规则会根据当前路径不同而不同

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

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

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

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

服务器内部路径:/hello

结论:web访问中所有资源路径,都使用绝对路径

三,init方法中的ServletConfig对象

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

ServletConfig对象和配置文件相关,其中的几个方法如下:

String getServletName() :获取配置文件中servlet的名称;

String getInitParameter(String name):获取初始化参数;

Enumeration getInitParameterNames():获取初始化参数的名称们

四,Web应用对象:ServletContext

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

ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。

ServletContext的作用:

1)获取WEB应用的全局初始化参数

 在web.xml中配置
<context-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</context-param>
String getInitParameter(String name)
getInitParameterNames()

2)通过ServletContext对象实现数据共享(案例— 统计站点访问次数

void setAttribute(String name, Object object)   存入数据
void removeAttribute(String name) 删除数据
Object getAttribute(String name) 获取数据

3)利用ServletContext对象读取资源文件

InputStream getResourceAsStream(String path)    通过文件的地址获取输入流
String getRealPath(String path) 通过文件的地址获取文件的绝对磁盘路径

五,web project中读取文件总结

1,文件系统路径:getServletContext().getRealPath(“/WEB-INF/info.txt”)

2,类路径:classpath (src下):

1)通过字节码对象读取 Class getResource(“/info.txt”).getFile()

2)获取字节码对象 Class

类名.class —- 静态方法

对象.getClass() —- 实例方法

举例说明:读取web工程中资源文件

在text工程中创建四个文件

1、在text工程根目录创建 1.txt

2、在WebRoot下创建2.txt

3、在WEB-INF下创建3.txt

4、在src下创建4.txt

使用带有main函数java程序(Java Application)读取文件,可以使用相对路径和绝对路径 ,在Servlet中读取资源文件,必须使用磁盘绝对路径。

1.txt—>因为在WebRoot 外面,不会发布到tomcat服务器,无法在服务器端读取

2.txt — > getServletContext().getRealPath(“/2.txt”);

3.txt — > getServletContext().getRealPath(“/WEB-INF/3.txt”);

4.txt 位于src下,复制到WEB-INF/classes下 —> getServletContext().getRealPath(“/WEB-INF/classes/4.txt”);

通用classpath下文件读取方法 (用来加载器读取)

XXX.class.getResource(“/4.txt”).getFile();

这里/代表classpath根目录(src 、WEB-INF/classes)

1、java读取
public static void main(String[] args) throws IOException {
// 编写四个文件路径,调用readfile方法 完成文件读取
// 读取1.txt
String filename1 = "1.txt";
readfile(filename1);
// 读取2.txt
String filename2 = "WebRoot/2.txt";
readfile(filename2);
// 读取3.txt
String filename3 = "WebRoot/WEB-INF/3.txt";
readfile(filename3);
// 读取4.txt
String filename4 = "src/4.txt";
readfile(filename4);
// 读取4.txt
String filename5 = FileReaderTest.class.getResource("/4.txt").getFile();
readfile(filename5);
} public static void readfile(String filename) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}
2、Servlet读取
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 读取 1.txt (不会被发布到tomcat,没法读)
// 读取 2.txt
String filename1 = "/2.txt";
// 根据相对于网站根目录绝对路径 ---- 获得磁盘绝对路径
filename1 = getServletContext().getRealPath(filename1);
System.out.println(filename1);
readfile(filename1);
// 读取3.txt
String filename2 = getServletContext().getRealPath("/WEB-INF/3.txt");
readfile(filename2);
// 读取4.txt
String filename3 = getServletContext().getRealPath(
"/WEB-INF/classes/4.txt");
readfile(filename3);
// 读取4.txt 用类加载器读取
String filename4 = ReadFileServlet.class.getResource("/4.txt")
.getFile();
readfile(filename4);
}
public static void readfile(String filename) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}