目录
ServletContext对象用于获取上下文路径(所谓的上下文路径,其实就是项目名称)
1、Tomcat简介
因为Servlet是在容器中运行的,这里用的容器是Tomcat。Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet 和 JSP 的支持。Tomcat 本身也内含了一个 HTTP 服务器,它也可以被视作一个单独的 Web 服务器,但是注意,但是,不能将 Tomcat 和 Apache HTTP 服务器混淆。
2、Servlet的生命周期简介
- Servlet对象的创建
- 由Tomcat去new一个Servlet对象
- init() Servlet的初始化
- init 方法只会在第一次创建的时候被调用一次,在后续的过程中不会再被调用;
- service() Servlet的服务方法,用来处理客户端请求
- service方法是执行实际任务的主要方法。Servlet容器调用service方法来处理来自客户端的请求,并把格式化的响应写会给客户端;
- 每一次服务器收到一个来自客户端的请求,服务器就会产生一个新的线程并调用服务;
- service方法会检查HTTP请求类型(get、post、put、delete...等),并在适当的时候调用 doGet() / doPost() / doPut() / doDelete()...等方法;
- destory() Servlet的终止、结束方法
- destory也只会被调用一次,在Servlet生命周期结束的时候被调用 ;
- destory 方法可以让你的Servlet关闭数据库连接,停止后台线程等执行相应的清理活动。
- 最后,由JVM进行垃圾回收
3、用代码模拟声明周期的全过程
public class LifeCycle extends HttpServlet {
// 自己写的无参构造,用来模拟对象创建
public LifeCycle ()
{
System.out.println("servlet 对象被创建...");
}
//覆写init方法,模拟初始化
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("servlet 被初始化...");
}
// 覆写服务方法,模拟处理客户端请求
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("servlet 服务方法被调用...");
}
// 覆写销毁方法,模拟销毁servlet方法
@Override
public void destroy() {
System.out.println("Servlet 被销毁...");
}
}
然后打开三个网页发起请求,如图:
然后运行结果:
从运行结果中也能看出来,当有多个客户端请求服务器时,servlet对象只会创建一次,初始化一次,然后每来一个请求就创建一个线程调用一次服务方法处理请求。如下图所示:
4、ServletConfig对象
在上面覆写init方法的时候,覆写的是 init( ServletConfig config) ,有一个参数,其实在源码中(GenericServlet 这个类里面),还有一个init方法,是没有参数的。
两个方法如下:
// 这一个方法有一个参数,是用于获取配置信息的时候用的,servlet生命周期的初始化就使用的这个方法
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
// 这个方法是Servlet初始化的简便方法,比如 用户自定义参数的时候使就可以使用这个方法
public void init() throws ServletException {
}
那么怎么获取那个config对象呢???
初始化参数:当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init方法传入一个ServletConfig。ServletConfig封装可以通过部署描述符传给Servlet的配置信息。这样传入的一条信息就叫初始化参数,一个初始化参数由key 和 value组成。
获取初始化参数:为了从Servlet内部获取到初始化参数的值,要找Servlet容器传给Servlet的init方法的ServletConfig中调用getInitParameter方法获取。
举个例子:
运行结果:
可是这么弄有什么用呢???
比如:现在有一个需求,要读取 aaa.txt 的文件内容,等你刚写完,需求又变为读取bbb.txt的文件内容......在实际工作中一般不会频繁的改变源码,所以这个时候我们就要读取的文件放在web.xml中。配置如下:
案例:读取文件内容:
public class ReadFileServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取config对象
ServletConfig config = this.getServletConfig();
// 获取路径
String path = config.getInitParameter("path");
// 按行读取文件
String str ;
BufferedReader br = new BufferedReader(new FileReader(path));
while ((str=br.readLine()) != null)
{
System.out.println(str);
}
}
}
5、ServletContext对象
ServletContext对象用于获取上下文路径(所谓的上下文路径,其实就是项目名称)
案例:获取上下文路径
public class ContextDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = this.getServletContext();
System.out.println(context.getContextPath());
}
}
运行结果: