黑马程序员技术交流社区
标题: 【上海校区】海哥解惑-Java读取项目资源文件的三种方式 [打印本页]
作者: 焚寂Ooo 时间: 2017-7-24 10:50
标题: 【上海校区】海哥解惑-Java读取项目资源文件的三种方式
本帖最后由 焚寂Ooo 于 2017-7-24 10:50 编辑
对于在一个javaweb应用,我们需要读取一个web程序运行时所需要的资源文件,比如下图这三个位置的读取。
这三个地方的分别是JavaWeb应用下WEN-INF目录下,src下(在Web应用中其实是在WEN-INF目录下的classes目录中),还有一个是在包名下(其实WEN-INF目录下的classes目录中的层次子目录),我们分别取名是a1.properties,a2.properties,a3.properties。对于这三个地方我们用三种方式来读取。
第一种:ServletContent对象读取
ervletContent对象只能适用于Web环境下,因为它是Servlet规范下的一个子对象。是在JavaEEAPI中,在Web环境下,这三个位置,ServletContext都能读取到。
提示:这里就用到ServletContext对象的方法getRealPath(String path),使用这方法的好处是始终是相对Web应用读取的路径,即使Web应用转移了,这个路径没有任何问题。
getRealPath(String path)使用方法:为给定虚拟路径返回包含实际路径的 String。比如例如,可以通过对"http://host/contextPath/index.html" 的请求使路径"/index.html" 返回服务器文件系统上(即JavaWeb应用的目录层次)的绝对文件路径,其中 contextPath 是此 ServletContext 的上下文路径。找不到则此方法返回 null。
读取第一个位置a1的代码如下:
[Java] 纯文本查看 复制代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获得ServletContext对象
ServletContext context=getServletContext();
//读取a1.properties
String path=context.getRealPath("/WEB-INF/a1.properties");
//获得的是Web上下文路径
String str=context.getContextPath();
System.out.println(str);//打印/myDay06
//读取该配置文件里面的值
Properties pro= new Properties();
pro.load(new FileInputStream(path));
String value=pro.getProperty("name1");
//打印到浏览器上
resp.getOutputStream().write(value.getBytes());
}
读取第二个位置a2示例代码如下:
[Java] 纯文本查看 复制代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获得ServletConext对象
ServletContext context=getServletContext();
String path=context.getRealPath("/WEB-INF/classes/a2.properties");
//读取到配置文件中
Properties pro=new Properties();
pro.load(new FileInputStream(path));
String value=pro.getProperty("name2");
//输出到浏览器
resp.getOutputStream().write(value.getBytes());
}
读取a3位置的示例代码如下:
[Java] 纯文本查看 复制代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletContext context=getServletContext();
String path=context.getRealPath("/WEB-INF/classes/com/lsh/resource/a3.properties");
//读取到配置文件中
Properties pro=new Properties();
pro.load(new FileInputStream(path));
String value=pro.getProperty("name3");
resp.getOutputStream().write(value.getBytes());
}
第二种:ResourceBundle对象读取
ResourceBundle对象是属于JavaSe中API的类,只能读取类路径下资源,且这个资源必须是porpperties扩展名的文件。由于其对象的特殊性它无法读取web环境下WEB-INF目录下的a1.properties处的文件位置。这个对象常用方法有:
b) public final
String getString(
String key): 从此资源包或它的某个父包中获取给定键的字符串。调用此方法等同于调用
(String) getObject(key)。
读取a2位置处的资源的代码如下:
[Java] 纯文本查看 复制代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//创建资源包对象,通过资源的不带扩展名的资源名称,基名
ResourceBundle bundle=ResourceBundle.getBundle("a2");
//通过资源中key值来得到value值
String value=bundle.getString("name2");
//输出到浏览器上
resp.getOutputStream().write(value.getBytes());
}
读取a3位置的话,由于是在包内,所以可通过java中的包名声明再加上资源的不带扩展名的名称。示例代码如下:
[Java] 纯文本查看 复制代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获得资源包对象
ResourceBundle bundle=ResourceBundle.getBundle("com.lsh.resource.a3");
//通过key值获得value值
String value=bundle.getString("name3");
resp.getOutputStream().write(value.getBytes());
}
第三种:通过类加载对象
类加载对象即ClassLoader
对象,通过该对象的getResourceAsStream(String name)方法,传入资源的相对路径和资源文件名,获得一个输入流InputStream,再通过Properties对象来得到文件里面的配置信息。这类做法是比较专业的。同样它也只能读取非web环境下的类路径,不能读取a1文件,但它能读取任何类型的文件。ClassLoader对象的获得可以通过类的字节码对象来获得一个类加载器对象。同样的,该对象也无法读取WEB-INF下配置文件。 读取a2文件的示例代码如下:
[Java] 纯文本查看 复制代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 获得的ClassLoader对象
ClassLoader loader = ServletContextReadSource2.class.getClassLoader();
//读取配置文件资源
InputStream in = loader.getResourceAsStream("a2.properties");
Properties pro = new Properties();
pro.load(in);
String value = pro.getProperty("name2");
System.out.println(value);
};
读取在包下面的a3,前面不能有斜杠。示例代码如下:
[Java] 纯文本查看 复制代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//创建ClassLoader对象
ClassLoader loader=ServletContextReadSource2.class.getClassLoader();
//通过资源的相对路径和名称来得到一个输入流
InputStream in=loader.getResourceAsStream("com/lsh/resource/a3.properties");
Properties pro=new Properties();
pro.load(in);
String value=pro.getProperty("name3");
System.out.println(value);
}
Web中常见资源路径写法
1. 绝对路径和相对路径
a) 相对路径前面不需要加斜杠。
b) 绝对路径钱需要加斜杠。在web应用中,斜杠代表的是当前应用。(建议使用)
2. Web中URL地址的写法原则:在URL路径时,首先判断地址是不是服务器来使用的。如果是,就加上“/”,来代表当前应用,建议使用。比如web应用名是myapp。需要访问的资源是myservlet。这时就不需要加上/myapp。直接以斜杠代表当前应用,可以直接在浏览器地址上写为/myservlet;如果不是,是给你客户端使用的URL地址,需要加上应用名,就这样写/myapp/myservlet。
例如以下常见的例子(path代表要填写的url,比如当前的应用名[虚拟路径]是myapp):
常见例子 | url规则 |
<link href=path/> | 要加/myapp |
<script src=path/> | 要加/myapp |
<img src=path/> | 要加/myapp |
<a href=path/> | 要加/myapp |
RequestDispatcher.include(path) | 不要加,"/"就代表着当前应用 |
RequestDispatcher.forward(path) | 不要加,"/"就代表着当前应用 |
HttpServletResponse.sendRedirect(path) | 要加/myapp |
ServletContext.getRealPath(path) | 不要加,"/"就代表着当前应用 |
作者: 执迷不悟 时间: 2017-7-24 10:53
厉害了我的哥
作者: 风雨过客 时间: 2017-7-24 11:04
可以的,666
作者: 小影姐姐 时间: 2017-7-24 11:13
不错,顶一个
作者: tangpeng520 时间: 2017-7-24 12:28
老铁
给力
作者: zhangzhijun 时间: 2017-7-24 15:25
厉害!
作者: 剑客贱不贱 时间: 2017-7-24 15:29
厉害了我的海
作者: fudo2016 时间: 2017-7-24 15:30
大牛,跟你学习!!!!!!!!!!!!!
作者: 默默呜呜 时间: 2017-7-24 15:35
作者: xiaokaibo 时间: 2017-7-24 15:36
学习了,66666666666666
作者: wjtang 时间: 2017-7-24 15:41
学习,学习
作者: IT界的小清新 时间: 2017-7-24 17:06
厉害了,我的天
作者: 陶亚伟 时间: 2017-7-24 18:00
(ノಥ益ಥ)友谊的小船
作者: 天涯不断 时间: 2017-7-24 18:01
犀利
作者: nulidxiaobai 时间: 2017-7-26 11:40
成功解惑
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |