ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题

        ClassLoader,小名类加载器,听起来好高大上滴样子,网上大神的解释更是深奥,刚刚入门,难以理解。我对它的理解就是加载一些文件用的,最常用的就是一个叫getResourceAsStream()的方法,它是用来加载一些配置文件的。好了,入题:

 

  1.   java项目下读取文件,我们创建一个java project,并创建一个包,一个类,在src目录下建立一个config.properties文件,注意:这个配置文件位置是和包同级的,不是和包下的类同级的。如下图:

       


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第1张图片

 


代码如下:

package com.hncj.edu;

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

public class PathTest {
	public static void main(String[]args) {
		ClassLoader cl = PathTest.class.getClassLoader();//获取类加载器对象
		InputStream is=cl.getResourceAsStream("config.properties");//注意路径
		if(is!=null) {
			Properties pr=new Properties();
			try {
				pr.load(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println(pr.getProperty("username")); //读取文件属性
			System.out.println(pr.getProperty("password")); //读取文件属性
		}else {
			System.out.println("加载失败!");
		}
	}
}

 程序正常运行,读取文件成功,但将配置文件作如下调整时(即将配置文件放在包下,和.java文件同级):


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第2张图片

 


路径需要做如下调整:


package com.hncj.edu;

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

public class PathTest {
	public static void main(String[]args) {
		ClassLoader cl = PathTest.class.getClassLoader();
		InputStream is=cl.getResourceAsStream("com/hncj/edu/config.properties");//注意路径变化
		if(is!=null) {
			Properties pr=new Properties();
			try {
				pr.load(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println(pr.getProperty("username"));
			System.out.println(pr.getProperty("password"));
		}else {
			System.out.println("加载失败!");
		}
	}
}

结论:两幅图对比可知,类加载器的路径相对于java文件编译后存放的bin目录而言的:

开始bin目录是这样的:


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第3张图片


后来是这样的:


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第4张图片


而且类加载器只能加载类目录下的文件,其他目录的加载不了。

2  动态web项目也是同样的道理,唯一的区别是此时的相对路径不同,此时相对的是部署后的WEB-INF下的classes目录.


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第5张图片


类似的代码:


package com.hncj.edu;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(asyncSupported = true, urlPatterns = { "/MyServlet" })
public class MyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ClassLoader cl = this.getClass().getClassLoader();
		InputStream is = cl.getResourceAsStream("/com/hncj/edu/config.properties");
    
          //上面一行路径最前面的斜杠可加可不加,斜杠相当于WEB-INF/classes/
        
		if(is!=null) {
			Properties pr=new Properties();
			pr.load(is);
			System.out.println(pr.getProperty("username"));
			System.out.println(pr.getProperty("password"));
		}else {
			System.out.println("加载失败!");
		}
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

同样的问题是,这个类加载器不能加载类目录之外的文件,比如说将配置文件放在WebRoot下面,这样根本没法写路径,更别提加载文件了。

解决这个问题可以使用ServletContext对象,既可以加载类目录里的文件,也可以加载WebRoot下的文件。

如下:


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第6张图片


package com.hncj.edu;

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

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(asyncSupported = true, urlPatterns = { "/MyServlet" })
public class MyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*ClassLoader cl = this.getClass().getClassLoader();
		InputStream is = cl.getResourceAsStream("/com/hncj/edu/config.properties");
		if(is!=null) {
			Properties pr=new Properties();
			pr.load(is);
			System.out.println(pr.getProperty("username"));
			System.out.println(pr.getProperty("password"));
		}else {
			System.out.println("加载失败!");
		}*/


            //下面是使用servletContext对象加载资源文件


		ServletContext servletContext = this.getServletContext();
		InputStream is = servletContext.getResourceAsStream("/WEB-INF/config.properties");
		Properties pr=new Properties();
		pr.load(is);
		System.out.println(pr.getProperty("username"));
		System.out.println(pr.getProperty("password"));
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

此时路径最前面的斜杠代表的是当前的应用,如我的工程是Web8,那就是Web8/,有人可能会问?为什么不是Web8/WebContent/,是因为项目部署以后没有WebContent这一目录。如下图:


ClassLoader的getResourceAsStream方法使用及在java和web项目中的路径问题_第7张图片

 

你可能感兴趣的:(Servlet)