4.5.3 访问资源文件

优质
小牛编辑
140浏览
2023-12-01

ServletContext接口定义了三个方法来访问当前Web应用程序的资源文件,这三个方法如下:

l getResourcePaths方法

该方法返回指定Web应用程序目录中的所有子目录和文件,这些返回的目录文件不包括嵌套目录和文件。这些返回的子目录和文件都封装在该方法返回的一个Set对象中。getResourcePaths方法的定义如下:

public Set getResourcePaths(String path);

其中path参数表示Web应用程序中的目录,必须以斜杠(/)开头,表示Web应用程序的根目录。如要得到WEB-INF目录中的所有目录和文件,可以使用如下的代码:

Set paths = getServletContext().getResourcePaths("/WEB-INF");

2  getResource方法

该方法返回指定Web应用程序中某个资源的URL对象,getResource方法的定义如下:

public URL getResource(String path) throws MalformedURLException;

其中path表示资源的路径,必须以斜杠(/)开头,表示Web应用程序的根目录。如要得到封装web.xml文件路径的URL对象,可以使有下面的代码:

URL url = getServletContext().getResource("/WEB-INF/web.xml");

3  getResourceAsStream方法

该方法返回某个资源的InputStream对象,getResourceAsStream方法实际上打开的是getResource方法返回的URL所指的资源文件。该方法的定义如下:

public InputStream getResourceAsStream(String path);

其中path参数的含义和getResource方法中的path参数相同。

除了使用ServletContext定义的方法来访问Web应用程序中的资源外,还可以使用如下的两种方法来访问资源文件:

1. 使用FileInputStream来访问资源文件

使用这种方法非常直接,但要通过ServletContext接口的getRealPath方法获得当前Web应用程序的本地目录。如打开web.xml文件的代码如下:

String resourceFileName = getServletContext().getRealPath("/WEB-INF/web.xml");

FileInputStream fis = new FileInputStream(resourceFileName);

要注意的是,FileInputStream可以打开以绝对路径指定的资源文件,也可以打开以相对路径指定的资源文件。如果使用相对路径,该相对路径是相对于当前路径而言的。Web服务器的当前路径可以使用如下的代码获得:

String path = System.getProperty("user.dir");

假设上面的代码返回的路径是D:\eclipse,如果在该目录下有一个abc子目录,并且在abc子目录中有一个xyz.properties目录,也就是说,xyz.properties文件的绝对路径是D:\eclipse\abc\xyz.properties,那么使用绝对路径和相对路径访问xyz..properties文件的代码如下:

//  使用绝对路径访问xyz.properties文件

FileInputStream fis1 = new FileInputStream("D:\eclipse\abc\xyz.properties");

//  使用相对路径访问xyz.properties文件

FileInputStream fis1 = new FileInputStream("abc\xyz.properties");

2. 使用Class.getResourceAsStream方法访问资源文件

Class的getResourceAsStream方法和ServletContext接口的getResourceAsStream方法虽然方法名相同,但却有一定的差异。

Class的getResourceAsStream方法的定义如下:

public InputStream getResourceAsStream(String name);

其中name表示资源的路径,也是以斜杠(/)开头,但这个斜杠是指WEB-INF\classes目录,而ServletContext接口中定义的getResourceAsStream方法的path参数中的斜杠是指Web应用程序的根目录。这一点在使用时要注意。

假设在WEB-INF\classes\chapter4目录中有一个abc.properties文件,使用Class.getResourceAsStream方法访问该文件的代码如下:

InputStream is = getClass().getResourceAsStream("/chapter4/abc.properties");

一个良好的编程习惯是将动态的或可能变化的信息(如连接数据库的信息、连接网络的信息等)保存在资源文件中,以便更容易修改和维护这些资源。

在下面的示例中演示了如何使用上述的三种方法来访问Web应用程序中的资源文件,并从中读取信息。

例子 : 演示访问Web应用程序资源的三种方法

1. 实例说明

本示例分别使用如下的三种方法来访问database.properties文件:

l ServletContext.getResourceAsStream方法

2  Class.getResourceAsStream方法

3  FileInputStream

database.properties文件中内容如下:

server=localhost

database=mydb

username=root

password=1234

在本例中将访问两个位置中的database.properties,一个位置是WEB-INF目录,另一个是WEB-INF\classes\chapter4目录。

在本例中,还演示了getResource方法和getResourcePaths方法的用法。

2. 编写ResourceServlet类

ResourceServlet类是一个Servlet类,在该类的service方法中通过上述的三种方式读取了database.properties文件中的内容,并输出的客户端浏览器。ResourceServlet类的代码如下:

package chapter4;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.Properties;

import java.net.URL;

public class ResourceServlet extends HttpServlet

{

    //  从InputStream对象中读取信息,并输出到PrintWriter对象中

    private void outProperties(InputStream is, PrintWriter out) throws Exception

    {

        Properties props = new Properties();    //  建立Properties对象

//  装载InputStream对象,并按着Java属性文件的格式进行分析

        props.load(is);

        //  输出属性文件中的信息

        out.println("server=" + props.getProperty("server") + "<br/>");

        out.println("database=" + props.getProperty("database") + "<br/>");

        out.println("username=" + props.getProperty("username") + "<br/>");

        out.println("password=" + props.getProperty("password") + "<br/>");

 

    }

    protected void service(HttpServletRequest request,

            HttpServletResponse response) throws ServletException, IOException

    {

        response.setContentType("text/html; charset=UTF-8");

        PrintWriter out = response.getWriter();

        try

        {

            //  用getResource方法返回WEB-INF目录中database.properties文件的URL对象

            URL url = getServletContext().getResource("/WEB-INF/database.properties");

            out.println(url.toString());

            out.println("<p/><p/>");

            //  得到/WEB-INF/database.properties文件的本地目录

            String resourceFileName = getServletContext().getRealPath("/WEB-INF/database.properties");

            //  使用FileInputStream访问/WEB-INF/database.properties文件

            FileInputStream fis = new FileInputStream(resourceFileName);

            out.println("使用FileInputStream读取属性文件中的内容<br/>");   

            outProperties(fis, out);

            //  使用ServletContext.getResourceAsStream访问

            //  /WEB-INF/database.properties文件

            InputStream is = getServletContext().getResourceAsStream("/WEB-INF/database.properties");

            out.println("<br/>");

            out.println("使用ServletContext.getResourceAsStream读取属性" + "文件中的内容<br/>");       

            outProperties(is, out);

            //  使用Class.getResourceAsStream方法访问

//  /WEB-INF/classes/chapter4/database.properties文件

            is = getClass().getResourceAsStream("/chapter4/database.properties");

            out.println("<br/>");

            out.println("使用Class.getResourceAsStream读取属性文件中的内容<br/>");       

            outProperties(is, out);

            out.println("<br/>");

            out.println("WEB-INF中的子目录和文件列表<br/>");       

            //  得到/WEB-INF目录中的所有子目录和文件

            java.util.Set<String> paths =this.getServletContext().getResourcePaths("/WEB-INF");

//  输出/WEB-INF目录中的子目录和文件

            for(String path: paths)

            {

                out.println(path + "<br/>");

            }

        }

        catch (Exception e)

        {

            out.println(e.getMessage());

        }

    }

}

在上面的代码中,使用了ServletContext.getResourceAsStream方法和FileInputStream来访问/WEB-INF/database.properties文件,使用了Class.getResourceAsStream方法来访问/WEB-INF/classes/chapter4/database.properties文件。并通过Properties对象来分析database.properties文件中的内容。该功能是由outProperties方法完成的。

ResourceServlet类的配置代码如下:

<servlet>

  <servlet-name>ResourceServlet</servlet-name>

  <servlet-class>chapter4.ResourceServlet</servlet-class>

</servlet>

<servlet-mapping>

  <servlet-name>ResourceServlet</servlet-name>

  <url-pattern>/ResourceServlet</url-pattern>

</servlet-mapping>

3. 测试ResourceServlet类

在浏览器中输入如下的URL:

http://localhost:8080/demo/ResourceServlet

浏览器中显示的信息如图4.8所示。

08

图4.8 输出database.properties文件中的内容