ServletContext详解

web容器在启动时,为每个web应用都创建了一个对应的ServletContext对象,所以ServletContext对象就代表着当前的web应用,在停掉服务器或删除某个web应用时,ServletContext对象就会销毁

获取ServletContext对象的方法

1、调用getServletConfig()方法的getServletContext()方法

ServletContext context = this.getServletConfig().getServletContext();

2、直接调用getServletContext()方法

ServletContext context = this.getServletContext();

ServletContext方法的应用

1、通过ServletContext实现数据共享:
一个web应用中所有的Servlet共用同一个ServletContext对象,所以多个Servlet通过一个ServletContext对象实现数据共享,ServletContext对象又被成为context域对象。
ServletContext域:这是一个容器,说明了容器的作用范围,即web应用程序的范围。


在一个Servlet文件ServletDemo1中写如下代码

String data = "aaa";
this.getServletContext().setAttribute("data", data);

要实现数据共享,另一个Servlet文件ServletDemo2必须getAttribute(String name),才能获得所需要的数据

String value = (String) this.getServletContext().getAttribute("data");
System.out.println("data:"+value);

实际开发中,用于聊天室的开发

2、获取web应用的初始化参数
web.xml文件中添加<context-param>元素,即为整个web应用配置初始化参数,服务器在加载web应用时,就自动配置了初始化参数,在ServletContext对象创建出来时,就自动被封装到ServletContext对象中,这时候只需要直接取这些初始化参数就行。
web.xml文件配置:

 <context-param>
    <param-name>data</param-name>
    <param-value>xxxx</param-value>
 </context-param>

ServletDemo中获得初始化参数(与ServletConfig类似):

this.getServletContext().getInitParameter("data");

实际开发中,用于连接数据库,url,username,password

3、实现Servlet的转发
首先搞清楚转发和重定向的区别:

  • 转发:一次请求,一次响应。地址栏的url不会改变。在服务器端执行,所以必须在同一台服务器上。转发速度快。
  • 重定向:两次请求。地址栏的url会随之改变为定向后的那个url。在客户端执行,所以可以在不同的服务器上。重定向速度慢。

通俗的来讲,这就类似于借钱,转发类似于,A找B借钱,B没有,B帮忙找到C借钱;重定向类似于,A找B借钱,B没有,B让A自己去找C借钱,其中一个是由服务器执行,只有一次url,客户机只有一次请求,另一个是由客户端执行,url由原来的url变成了一个新的url,客户机请求了两次,所以转发速度快,重定向速度慢,转发实际应用比重定向多。

4、利用ServletContext对象读取资源文件
软件开发中写配置文件,类型:.xml或.properties,若数据有关系,用.xml文件,数据没有关系,用.properties文件
如:数据库连接,用.properties文件,在src上点击新建file,新建db.properties文件,输入url,username,password

url=jdbc:mysql://localhost:3306/test
username=root
password=root

要读取该资源文件,通过getServletContext()方法,获取该web应用,然后通过getResourceAsStream()方法,获得该web应用下资源文件的路径,不提倡直接使用FileInputStream()方法读取,这样用相对路径获取的是相对web服务器启动程序的路径,麻烦。
新建Servlet文件,ServletDemo3,要根据db.properties文件放在不同的位置设置不同的路径,因为我的db.properties文件在tomcat的/webapps/TestServlet2/WEB-INF/CLASSES目录下,所以代码如下

InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(in);
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
System.out.println(url);
System.out.println(username);
System.out.println(password);

如果必须要使用FileInputStream读取资源文件,就要先通过:
getServletContext()获得该web应用,然后调用getRealPath()方法获得db.properties资源文件在硬盘上的绝对路径,然后再读取,代码如下

String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties"); //获得资源文件的绝对路径
FileInputStream in = new FileInputStream(path);
Properties prop = new Properties();
prop.load(in);
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
System.out.println(url);
System.out.println(username);
System.out.println(password);

该方法可用于下载文件,可以得到资源名称

String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");

String filename = path.substring(path.lastIndexOf("\\")+1);
System.out.println("资源名字是:"+filename);

普通java程序读取资源文件

我们一般需要操作数据库时,不直接在Servlet文件中操作数据库,而是调用UserDao的update()方法来操作数据库,所以要先新建UserDao类,放在com.servlet.dao包中。

package com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.servlet.dao.UserDao;

public class ServletDemo7 extends HttpServlet {

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

        UserDao dao = new UserDao();
        dao.update();
    }

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

        doGet(request, response);
    }

}

如果读取资源文件的程序不是Servlet,只能通过类装载器来读取资源文件
如下,新建UserDao.java文件

package com.servlet.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class UserDao {

    private static Properties dbconfig = new Properties();

    static {
        try {
            InputStream in = UserDao.class.getClassLoader().getResourceAsStream("db.properties");
            dbconfig.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public void update() {
        String url = dbconfig.getProperty("url");
    }

}

注:通过类装载器读取资源文件时,会把文件load到内存中,所以文件不能太大,以防内存溢出。这种方法虽然可以读取到资源文件中的数据,但是在数据更新后,它不可以读取到更新后的数据,因为类装载器只加载了一次,之后不会再重新加载。

如果要读取到更新后的资源文件的数据,不能通过类装载器读取,要通过FileInputStream流读取,这就需要先通过类装载器读取到文件位置,再读取文件中的数据,代码如下:

package com.servlet.dao;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

public class UserDao {
    public void update() {
        String path = UserDao.class.getClassLoader().getResource("db.properties").getPath();
        FileInputStream in = null;
        try {
            in = new FileInputStream(path);
            Properties dbconfig = new Properties();
            dbconfig.load(in);
            String url = dbconfig.getProperty("url");
            System.out.println(url);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Shine_rise/article/details/53947798