一,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自动加载:如果在
元素中配置了一个
元素,那么WEB应用程序在启动时,就会装载并创建Servlet的实例对象、以及调用Servlet实例对象的init()方法。
举例:
<servlet>
<servlet-name>invokerservlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
servlet-class>
<load-on-startup>2load-on-startup>
servlet>
二,配置Servlet路径映射配置:
由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用元素和元素完成。
元素:用于注册Servlet,它包含有两个主要的子元素:和,分别用于设置Servlet的注册名称和Servlet的完整类名。
一个元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:和,分别用于指定Servlet的注册名称和Servlet的对外访问路径。
例如:
<web-app>
<servlet>
<servlet-name>AnyNameservlet-name>
<servlet-class>HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>AnyNameservlet-name>
<url-pattern>/demo/hello.htmlurl-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">HelloServleta>
<a href="hello">HelloServleta>
<h1>绝对路径h1>
<a href="http://localhost/day/hello">HelloServleta>
<a href="/day/hello">HelloServleta>
2.html
<h1>相对路径h1>
<a href="../hello">HelloServleta>
<h1>绝对路径h1>
<a href="http://localhost/day/hello">HelloServleta>
<a href="/day/hello">HelloServleta>
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();
}