A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 焚寂Ooo 于 2017-7-24 10:50 编辑

对于在一个javaweb应用,我们需要读取一个web程序运行时所需要的资源文件,比如下图这三个位置的读取。

这三个地方的分别是JavaWeb应用下WEN-INF目录下,src下(在Web应用中其实是在WEN-INF目录下的classes目录中),还有一个是在包名下(其实WEN-INF目录下的classes目录中的层次子目录),我们分别取名是a1.propertiesa2.propertiesa3.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
[color=#ff0000]                String path=context.getRealPath("/WEB-INF/a1.properties");[/color]
                //获得的是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();
[color=#ff0000]                String path=context.getRealPath("/WEB-INF/classes/a2.properties");[/color]
                //读取到配置文件中
                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();
[color=#ff0000]                String path=context.getRealPath("/WEB-INF/classes/com/lsh/resource/a3.properties");[/color]
                //读取到配置文件中
                Properties pro=new Properties();
                pro.load(new FileInputStream(path));
                String value=pro.getProperty("name3");
                resp.getOutputStream().write(value.getBytes());
        }

第二种:ResourceBundle对象读取
ResourceBundle对象是属于JavaSeAPI的类,只能读取类路径下资源,且这个资源必须是porpperties扩展名的文件。由于其对象的特殊性它无法读取web环境下WEB-INF目录下的a1.properties处的文件位置这个对象常用方法有:
a)     public static final ResourceBundle getBundle(String baseName):通过资源的基名来得到一个资源包对象(ResourceBundle)。
b)    public final String getString(String key): 从此资源包或它的某个父包中获取给定键的字符串。调用此方法等同于调用
(String) getObject(key)。


读取a2位置处的资源的代码如下:
[Java] 纯文本查看 复制代码
@Override
                protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                                throws ServletException, IOException {
                        //创建资源包对象,通过资源的不带扩展名的资源名称,基名
[color=#ff0000]                        ResourceBundle bundle=ResourceBundle.getBundle("a2");[/color]
                        //通过资源中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 {
                        //获得资源包对象
[color=#ff0000]                        ResourceBundle bundle=ResourceBundle.getBundle("com.lsh.resource.a3");[/color]
                        //通过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();
                //读取配置文件资源
[color=#ff0000]                InputStream in = loader.getResourceAsStream("a2.properties");
                Properties pro = new Properties();
                pro.load(in);[/color]
                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();
                //通过资源的相对路径和名称来得到一个输入流
[color=#ff0000]                InputStream in=loader.getResourceAsStream("com/lsh/resource/a3.properties");
                Properties pro=new Properties();
                pro.load(in);[/color]
                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)         不要加,"/"就代表着当前应用













点评

good good study! day day up!  发表于 2017-7-24 10:54

评分

参与人数 5技术分 +10 黑马币 +22 收起 理由
Henry777 + 5
xiaokaibo + 5 赞一个!
fudo2016 + 1
绮丽 + 1 很给力!
上海分校-小影 + 10 + 10 神马都是浮云

查看全部评分

16 个回复

正序浏览
nulidxiaobai 来自手机 初级黑马 2017-7-26 11:40:07
15#
成功解惑
回复 使用道具 举报
犀利
回复 使用道具 举报
陶亚伟 来自手机 初级黑马 2017-7-24 18:00:34
13#
(ノಥ益ಥ)友谊的小船
回复 使用道具 举报
厉害了,我的天
回复 使用道具 举报
学习,学习
回复 使用道具 举报
学习了,66666666666666
回复 使用道具 举报
回复 使用道具 举报
大牛,跟你学习!!!!!!!!!!!!!
回复 使用道具 举报
厉害了我的海
回复 使用道具 举报
厉害!
回复 使用道具 举报
tangpeng520 来自手机 初级黑马 2017-7-24 12:28:25
报纸
老铁
给力
回复 使用道具 举报
不错,顶一个

点评

成功解惑~~~~~~~~~~  发表于 2017-8-1 10:45
回复 使用道具 举报
可以的,666
回复 使用道具 举报
厉害了我的哥
回复 使用道具 举报 1 0
您需要登录后才可以回帖 登录 | 加入黑马