JavaSE基础:Properties属性类

Properties

在Java中属性操作类是一个很重要的类,而要想明白属性操作类的作用,就必须先要清楚什么是属性文件,在属性文件中含有多个属性,每个属性就是直接用字符串表示出来的"key=value 键/值对", 而如果要想轻松操作这些属性需要使用Properties类完成.

1.简单认识Properties

public class Properties extends Hashtable<Object,Object>
复制代码
编号方法名称类型描述
1public Properties()构造创建一个无默认值的空属性类
2public Properties(Properties props)构造创建一个带有指定默认值的空属性类
3public String getProperty(String key)普通方法根据属性的key取得属性的value,如果没有,将放回null
4public String getProperty(String key, String defaultValue)普通方法根据属性的key取得属性的value,如果没有,将返回defaultValue
5public Object setProperty(String key, String value)普通方法设置属性
6public void list(PrintStream out)普通方法属性打印
7public void load(InputStream inStream)普通方法将输入流中取出全部的属性内容
8public void loadFromXML(InputStream in)普通方法从XML文件格式中读取内容
9public void store(OutputStream out, String comments)普通方法将属性内容通过输出流输出,同时声明属性的注释内容
10public void storeToXML(OutputStream os, String comment)普通方法以XML文件格式输出属性,默认编码
11public void storeToXML(OutputStream os, String comment, String encoding)普通方法以XML文件格式输出属性,用户指定默认编码

实际开发中我们使用Properties的功能类似于存储的数据为Map<String,String>都是字符串的形式

2.Properties的操作实例

示例1:设置和取得属性

主要使用setProperty()和getProperty()方法设置和获取属性,存储的数据类型都是String

package com.shxt.demo06;

import java.util.Properties;

public class Demo01 {
    public static void main(String[] args) {
        Properties props = new Properties(); //创建Properties对象
        //设置属性
        props.setProperty("title","胖先森博客");
        props.setProperty("version","v1.0");
        props.setProperty("db","MySQL 5.7");

        //获取属性
        System.out.println("1.title属性存在:"+props.getProperty("title"));
        System.out.println("2.name属性不存在:"+props.getProperty("name"));
        System.out.println("3.name属性不存在,显示默认值:"+props.getProperty("name","胖先森"));

    }
}
/*
	运行结果:
		1.title属性存在:胖先森博客
        2.name属性不存在:null
        3.name属性不存在,显示默认值:胖先森
*/
复制代码

示例2:保存属性到普通的属性文件

package com.shxt.demo06;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class Demo02 {
    public static void main(String[] args) {
        Properties props = new Properties(); //创建Properties对象
        //设置属性
        props.setProperty("title","胖先森博客");
        props.setProperty("version","v1.0");
        props.setProperty("db","MySQL 5.7");

        //设置属性文件的保存路径,使用绝对路径
        //关于文件的操作,我们在后面J2EE文件上传的时候会再次说明
        File file = new File("D:/sys.properties");
        try {
            props.store(new FileOutputStream(file),"system config");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
复制代码

运行结果:

说明:如果是中文会使用Unicode进行转换

示例3:从属性文件中读取内容

package com.shxt.demo06;

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

public class Demo03 {
    public static void main(String[] args) {
        Properties props = new Properties(); //创建Properties对象

        //跟磁盘中的文件建立联系
        File file = new File("D:/sys.properties");
        try {
            //读取属性文件
            props.load(new FileInputStream(file));
            //获取属性
            System.out.println("getProperty():"+props.getProperty("title"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/*
	运行结果:
		getProperty():胖先森博客
*/
复制代码

下面的简单了解就好

示例4:将属性文件保存到XML文件中

package com.shxt.demo06;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class Demo04 {
    public static void main(String[] args) {
        Properties props = new Properties(); //创建Properties对象
        //设置属性
        props.setProperty("title","胖先森博客");
        props.setProperty("version","v1.0");
        props.setProperty("db","MySQL 5.7");

        //跟磁盘中的文件建立联系,文件的后缀名必须为.xml
        File file = new File("D:/sys.xml");
        try {
            props.storeToXML(new FileOutputStream(file),"system config");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
复制代码

运行结果:

示例5:从XML文件中读取属性

package com.shxt.demo06;

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

public class Demo05 {
    public static void main(String[] args) {
        Properties props = new Properties(); //创建Properties对象

        //跟磁盘中的文件建立联系
        File file = new File("D:/sys.xml");
        try {
            //读取XML文件
            props.loadFromXML(new FileInputStream(file));
            //获取属性
            System.out.println("getProperty():"+props.getProperty("title"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/*
	运行结果:
		getProperty():胖先森博客
*/
复制代码

3.认识Properties文件

  • properties文件是一个文本文件
  • properties文件的语法有两种,一种是注释,一种属性配置。
    • 注释:前面加上#号
    • 属性配置:以"键=值"的方式书写一个属性的配置信息,都是字符串。
  • properties文件的一个属性配置信息值可以换行,但键不可以换行。值换行用“\”表示。
  • properties的属性配置键值前后的空格在解析时候会被忽略。
  • properties文件可以只有键而没有值。也可以仅有键和等号而没有值,但无论如何一个属性配置不能没有键。

不推荐的写法

#正确的properties配置文件 
aaa=wu\ 
    kong 
b
bb    =     bajie
复制代码

推荐的写法

#格式良好的properties文件 
aaa=wukong
bbb=bajie
复制代码

4.读取Properties文件的方法

(1) 使用java.util.Properties类的load()方法

你需要提供一共绝对路径读取数据,"D:/sys.properties"类似的路径,我个人不怎么推荐使用

package com.shxt.demo06;

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

public class Demo06 {
    public static void main(String[] args) {
       Properties props = new Properties();
        try {
            props.load(new FileInputStream("D:/sys.properties"));
            //获取属性
            System.out.println("title属性的值:"+props.getProperty("title"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

复制代码

(2) 使用java.util.ResourceBunld类的getBundle()方法[掌握]

通过ResourceBundle.getBundle()静态方法来获取(ResourceBundle是一个抽象类),这种方式来获取properties属性文件不需要加.properties后缀名,只需要文件名即可.

  • 属性文件在src的根目录下

package com.shxt.demo06;

import java.util.ResourceBundle;

public class Demo07 {
    public static void main(String[] args) {
       ResourceBundle resouce = ResourceBundle.getBundle("sys");
        //获取属性
        System.out.println("title属性的值:"+resouce.getString("title"));
    }
}
复制代码
  • 属性文件在包com.shxt.demo06
package com.shxt.demo06;

import java.util.ResourceBundle;

public class Demo08 {
    public static void main(String[] args) {
        //sys为属性文件名,放在包com.shxt.demo06下,如果是放在src下,直接用sys即可
       ResourceBundle resouce = ResourceBundle.getBundle("com/shxt/demo06/sys");
        //获取属性
        System.out.println("title属性的值:"+resouce.getString("title"));
    }
}
复制代码

(3) 使用PropertyResourceBundle

package com.shxt.demo06;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

public class Demo09 {
    public static void main(String[] args) {
        try {
            ResourceBundle resource =  new PropertyResourceBundle(new FileInputStream("D:/sys.properties"));
            //获取属性
            System.out.println("title属性的值:"+resource.getString("title"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
复制代码

(4) 使用class变量的getResourceAsStream()方法

package com.shxt.demo06;

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

public class Demo11 {
    public static void main(String[] args) {
		//  /config/sys.properties 从src的根目录开始查找,记住这个"/"
      	// 如果没有这个斜线,那么会报空指针异常
        InputStream in =  Demo11.class.getResourceAsStream("/config/sys.properties");
        Properties props = new Properties();
        try {
            props.load(in);
            //获取属性
            System.out.println("title属性的值:"+props.getProperty("db"));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

复制代码

(5) 使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法

package com.shxt.demo06;

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

public class Demo12 {
    public static void main(String[] args) {

        InputStream in =  Demo12.class.getClassLoader().getResourceAsStream("config/sys.properties");
        Properties props = new Properties();
        try {
            props.load(in);
            //获取属性
            System.out.println("title属性的值:"+props.getProperty("db"));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

复制代码

感觉上就是少了一个斜线而已

(6) 使用java.lang.ClassLoader类的getSystemResourceAsStream()静态方法[推荐]

package com.shxt.demo06;

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

public class Demo13 {
    public static void main(String[] args) {

        InputStream in =  ClassLoader.getSystemResourceAsStream("config/sys.properties");
        Properties props = new Properties();
        try {
            props.load(in);
            //获取属性
            System.out.println("title属性的值:"+props.getProperty("db"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

复制代码

7.补充:Servlet中可以使用javax.servlet.ServletContext的getResourceAsStream()方法

InputStream in = context.getResourceAsStream(path);
Properties p = new Properties();
p.load(in);
复制代码

5.技术穿越

这里分享一个简单的封装的工具类

package com.pangsir.helper.properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.Properties;


/**
 * 加载属性文件
 *
 * @author 刘文铭
 * @see com.pangsir.helper.properties.PropertiesConfigHelper
 * @since 1.0
 */
public class PropertiesConfigHelper {
    private PropertiesConfigHelper(){}

    //使用日志输出
    private final static Logger logger = LoggerFactory.getLogger(PropertiesConfigHelper.class);
    //设置后缀名
    private final static String EXT = ".properties";
    //实例化Properties对象
    private static Properties configProperties = null;

    /**
     * 加载properties文件
     *
     * @param filepaths properties文件路径
     */
    public static void load(String... filepaths) {
        logger.debug("开始读取properties文件 开始时间" + System.currentTimeMillis());
        if(configProperties==null){
            configProperties = new Properties();
        }
        //配置文件路径
        String configFilePath;
        InputStream inputStream = null;
        //遍历filepathke数组
        for (int i = 0; i < filepaths.length; i++) {
            configFilePath = filepaths[i];
            //读取属性文件后缀名为.properties
            try {
                if (configFilePath.toLowerCase().endsWith(EXT)) {
                    inputStream = PropertiesConfigHelper.class.getClassLoader().getResourceAsStream(configFilePath);
                    configProperties.load(inputStream);
                } else {
                    throw new RuntimeException("无法读取该文件: " + configFilePath);
                }
                logger.debug("文件 \"" + configFilePath + "\" 读取 成功! 时间为:" + System.currentTimeMillis());
            } catch (Exception e) {
                logger.debug("文件 \"" + configFilePath + "\" 读取 失败, 失败异常信息:\\n" + e.getMessage());
                throw new RuntimeException("文件 \"" + configFilePath + "\" 加载失败", e);
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        logger.debug("所有配置文件读取完毕,当关闭文件FileInputStream时,异常信息 :\\n" + e.getMessage());
                    }
                }
            }

        }

    }

    /**
     * 获取 int 类型的配置属性的value
     *
     * @param key          配置属性的key
     * @param defaultValue 默认值
     * @return 对应的配置属性value,如果配置属性的value不为short类型或不存在对应的配置属性,则返回 defaultValue
     */
    public static Short getShortValue(String key, Short defaultValue) {
        try {
            return getShortValue(key);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取 short 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static Short getShortValue(String key) {
        return Short.parseShort(configProperties.getProperty(key));
    }

    /**
     * 获取 int 类型的配置属性的value
     *
     * @param key          配置属性的key
     * @param defaultValue 默认值
     * @return 对应的配置属性value,如果配置属性的value不为int类型或不存在对应的配置属性,则返回 defaultValue
     */
    public static int getIntegerValue(String key, Integer defaultValue) {
        try {
            return getIntegerValue(key);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取 int 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static Integer getIntegerValue(String key) {
        return Integer.parseInt(configProperties.getProperty(key));
    }


    /**
     * 获取 float 类型的配置属性的value
     *
     * @param key          配置属性的key
     * @param defaultValue 默认值
     * @return 对应的配置属性value,如果配置属性的value不为float类型或不存在对应的配置属性,则返回 defaultValue
     */
    public static Float getFloatValue(String key, float defaultValue) {
        try {
            return getFloatValue(key);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取 float 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static Float getFloatValue(String key) {
        return Float.parseFloat(configProperties.getProperty(key));
    }

    /**
     * 获取 double 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @param defaultValue 默认值
     * @return 对应的配置属性value,如果配置属性的value不为double类型或不存在对应的配置属性,则返回 defaultValue
     */
    public static Double getDoubleValue(String key, double defaultValue) {
        try {
            return getDoubleValue(key);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }
    /**
     * 获取 Double 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static Double getDoubleValue(String key) {
        return Double.parseDouble(configProperties.getProperty(key));
    }



    /**
     * 获取 long 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @param defaultValue 默认值
     * @return 对应的配置属性value,如果配置属性的value不为long类型或不存在对应的配置属性,则返回 defaultValue
     */
    public static Long getLongValue(String key, long defaultValue) {
        try {
            return getLongValue(key);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }
    /**
     * 获取 Long 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static Long getLongValue(String key) {
        return Long.parseLong(configProperties.getProperty(key));
    }



    /**
     * 获取 String 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @param defaultValue 默认值
     * @return 对应的配置属性value,如果配置属性的value为""或不存在对应的配置属性,则返回 defaultValue
     */
    public static String getStringValue(String key, String defaultValue) {
        String value = configProperties.getProperty(key);
        return (value == null) ? defaultValue : getStringValue(key);
    }
    /**
     * 获取 String 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static String getStringValue(String key) {
        return configProperties.getProperty(key);
    }

    /**
     * 获取 boolean 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @param defaultValue 默认值
     * @return 如果在配置文件中没有定义此属性,则返回 defaultValue;
     *         如果 value 为y、on、yes 、true 或非 0 数值(均不区分大小写) 则返回 true, 否则返回 false
     */
    public static boolean getBooleanValue(String key, Boolean defaultValue) {
        String value = configProperties.getProperty(key);
        return (value == null) ? defaultValue : getBooleanValue(key);
    }
    /**
     * 获取 boolean 类型的配置属性的value
     *
     * @param key 配置属性的key
     * @return 对应的配置属性value
     */
    public static Boolean getBooleanValue(String key) {
        String value = configProperties.getProperty(key);
        return ("y".equalsIgnoreCase(value)) || ("on".equalsIgnoreCase(value)) || ("yes".equalsIgnoreCase(value))
                || ("true".equalsIgnoreCase(value)) || (getIntegerValue(key, 0) != 0);
    }
    /**
     * 加载properties文件
     *
     * @param filepath properties文件路径
     */
    public static void write(String key, String value,String filepath){
        if(configProperties==null){
            configProperties = new Properties();
        }

        OutputStream outputStream = null;
        try{
            String base = PropertiesConfigHelper.class.getResource("/"+filepath).getPath();
            java.net.URL url = PropertiesConfigHelper.class.getResource("/"+filepath);
            File file = new File(url.toURI());
            //判断文件是否存在
            if(!file.exists()){
                file.createNewFile();
            }

            load(filepath);//加载文件

            outputStream = new FileOutputStream(file);

            configProperties.setProperty(key,value);

            configProperties.store(outputStream,"");


        }catch (Exception e){
            throw new RuntimeException("文件 \"" + filepath + "\" 加载失败", e);
        }finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    logger.debug("所有配置文件修改完毕,FileOutputStream异常信息 :\\n" + e.getMessage());
                }
            }
        }

    }
}

复制代码

重点:将properties文件的配置设置为整个Web应用的全局变量实现方法,学到J2EE阶段再使用下面的方式

WEB域的简单说明:

Web应用中的变量存放在不同的jsp对象中,会有不一样的作用域,四种不同的作用域排序是 pageContext < request < session < application;

  • pageContext:页面域,仅当前页面有效,离开页面后,不论重定向还是转向(即无论是redirect还是forward),pageContext的属性值都失效;
  • request:请求域,在一次请求中有效,如果用forward转向,则下一次请求还可以保留上一次request中的属性值,而redirect重定向跳转到另一个页面则会使上一次request中的属性值失效;
  • session:会话域,在一次会话过程中(从浏览器打开到浏览器关闭这个过程),session对象的属性值都保持有效,在这次会话过程,session中的值可以在任何页面获取;
  • application:应用域,只要应用不关闭,该对象中的属性值一直有效,并且为所有会话所共享

思路说明:

利用ServletContextListener监听器,一旦应用加载,就将properties的值存储到application当中.

现在需要在所有的jsp中都能通过EL表达式读取到properties中的属性,并且是针对所有的会话,故这里利用application作用域,那么什么时候将properties中的属性存储到application呢?因为是将properties的属性值作为全局的变量以方便任何一次EL的获取,所以在web应用加载的时候就将值存储到application当中.

这里就要利用ServletContextListener:

  • ServletContextListener是Servlet API 中的一个接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。
  • 当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。

具体步骤:

  • (1) 新建一个类PropertyListenter实现 ServletContextListener接口的contextInitialized方法;
  • (2) 读取properties配置文件,转存到Map当中;
  • (3) 使用ServletContext对象将Map存储到application作用域中;
/**
 * 设值全局变量
 */
public class PropertyListenter implements ServletContextListener {
 private static final Logger logger = (Logger) LoggerFactory.getLogger(PropertyListenter.class);
 @Override
 public void contextDestroyed(ServletContextEvent context) {}
 @Override
 public void contextInitialized(ServletContextEvent sce) {
  /**
   * 读取properties文件
   */
  Properties properties = new Properties(); 
  
  InputStream in = null;
  try {
   //通过类加载器进行获取properties文件流
   in = PropertiesUtil.class.getClassLoader().getResourceAsStream("sys.properties");   
   properties.load(in);
   
  } catch (FileNotFoundException e) {
   logger.error("未找到properties文件");
  } catch (IOException e) {
   logger.error("发生IOException异常");
  } finally {
   try {
    if(null != in) {
     in.close();
    }
   } catch (IOException e) {
    logger.error("properties文件流关闭出现异常");
   }
  }
      
  /**
   * 将properties文件转存到map.关键步骤
   */
  Map<String, String> pros = new HashMap<String,String>((Map)properties);
  
  /**
   * 将Map通过ServletContext存储到全局作用域中
   */
  ServletContext sct=sce.getServletContext(); 
  
  sct.setAttribute("pros", pros);

 }
 

}
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值