How does java get the content of properties file dynamically in real time

  • 2021-11-13 07:30:36
  • OfStack

Directory real-time dynamic access to properties file content dynamic reading code reading configuration file Properties VS ResourceBundle1. Common API2. Properties analysis attribute file 3. ResourceBundle analysis attribute file 4. Attribute file 5. Practical recommendation

Get the content of properties file dynamically in real time

When you read the properties file with "ClassLoader. getResourceAsStream", you will find that after modification.properties, even if you re-execute it, you will still read in the parameters before modification.

The reason for this problem is that after ClassLoader. getResourceAsStream is read, the. properties is saved in the cache and is read from the cache when re-executed, instead of reading the. properties file again.

Dynamically read code


import java.util.Properties; 
/**
 *  Real-time dynamic acquisition properties The value of the file 
 * @author Administrator
 *
 */
public class demo01 {
 /**
  *  Get the values in the configuration file in real time according to the configuration variables 
  * @param key  Configuration name 
  * @param filePath  The configuration file pathname, for example: test.properties
  * @return  Configuration value 
  */
 public static String getCurrentPropertiesValue(String key,String filePath){
  String value="";
  Properties p = new Properties();
  try {
   // Non-real-time dynamic acquisition 
   //p.load(new InputStreamReader(this.class.getClassLoader().getResourceAsStream(filePath), "UTF-8"));
   // The following is a dynamic acquisition 
   String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
   InputStream is = new FileInputStream(path +File.separator+ filePath);
   p.load(is);
   value=p.getProperty(key);
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return value;
 }
}

Read configuration file Properties VS ResourceBundle

In java development, For some commonly used configurable information, It is usually stored in a properties file, Because modifying the configuration file does not require recompiling the jar package. For properties files, you can usually use the Properties and ResourceBundle classes to parse. Note that by default, the *. properties file encoding format in the java project is ISO-8859-1, and Properties and ResourceBundle also parse strings in properties files in the ISO-8859-1 format. Therefore, extra attention is needed when parsing familiar files containing Chinese.

ResourceBundle: Usually used to parse the internationalized resource properties file, which automatically selects the corresponding internationalized resource according to the local environment. Properties: Used to parse common properties files

1. Common API

1.1 Properties Common API

Properties inherits Hashtable < Object,Object > Class.

方法签名 方法描述
public String getProperty(String key 获取属性文件中的Key, 如果key不存在返回Null
public String getProperty(String key, String defaultValue) 获取属性文件中key对象的value, 如果key不存在则返回默认值defaultValue
public Object get(String key) 父类HashTable中的方法, 返回值类型为Object

1.2 ResourceBundle Common API

ResourceBundle is an interface that uses PropertyResourceBundle by default to parse properties files.

方法签名 方法描述
public Locale getLocale() 获取本地国际化环境
public Enumeration getKeys() 获取属性文件中所有key
public final String getString(String key) 获取属性文件中key对应的value, 返回值为String, 如果不存在, 则抛出异常
public final Object getObject(String key) 获取属性文件中key对应的value, 返回值为Object, 如果不存在, 则抛出异常

2. Properties Parsing Properties File

By default, ISO-8859-1 is used to parse the strings in the configuration file, so it will cause Chinese garbled codes.

2.1 Parsing English Configuration Files


//  Default encoding (ISO-8859-1) Read properties file ,  Chinese garbled code 
@Test
public void test_properties_en() throws IOException{
 
 //  Properties file location ,  The relative path is src/main/resources  Or  src/test/resources,  Cannot add classpath:/ Prefix 
 String propertyFileName = "jdbc.properties";
 
 //  Get byte stream 
 InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);
 
 //  Create a properties file ,  And load the file contents 
 Properties properties = new Properties();
 properties.load(is); 
 String username = properties.getProperty("jdbc.username");
 String password = properties.getProperty("jdbc.password");
 System.out.println("username:" + username + ", password:" + password); 
}

2.2 Parsing Configuration Files Containing Chinese

By default, ISO-8859-1 is used, and InputStreamReader is converted to UTF8 character stream.


//  Specify the encoding method for reading files , Support reading Chinese 
@Test
public void test_properties_zh() throws IOException{
 
 //  Properties file location ,  The relative path is src/main/resources  Or  src/test/resources,  Cannot add classpath:/ Prefix 
 String propertyFileName = "jdbc.properties";
 
 //  Get byte stream 
 InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);
 
 //  Convert to UTF-8 Format character stream 
 InputStreamReader isr = new InputStreamReader(is, "UTF-8");
 
 //  Create a properties file ,  And load the file contents 
 Properties properties = new Properties();
 properties.load(isr); 
 String username = properties.getProperty("jdbc.username");
 String password = properties.getProperty("jdbc.password");
 System.out.println("username:" + username + ", password:" + password); 
}

3. ResourceBundle Parsing Properties File

3.1 Parsing English Configuration Files


@Test
public void testRb_en() {
 //  Resource profile , No need to write file suffix ,  Default search properties Documents 
 String bundleName = "jdbc";
 
 //  Set the local default environment to English environment 
 Locale.setDefault(Locale.ENGLISH);
 
 //  Specify loading 
 ResourceBundle rb = ResourceBundle.getBundle(bundleName);
 
 String username = rb.getString("jdbc.username");
 String password = rb.getString("jdbc.password");
 System.out.println("username:" + username + ", password:" + password);
}

3.2 Parsing Configuration Files Containing Chinese


//  Processing Chinese 
@Test
public void testRb_zh() {
 //  Resource profile , No need to write file suffix ,  Default search properties Documents 
 String bundleName = "jdbc";
 
 //  Load the resource profile according to the local default environment 
 ResourceBundle rb = ResourceBundle.getBundle(bundleName); 
 String username = iso2Utf8(rb.getString("jdbc.username"));
 String password = iso2Utf8(rb.getString("jdbc.password"));
 System.out.println("username:" + username + ", password:" + password); 
}
/**
 * @Description iso Encoded format string is converted to UTF8 Format 
 * @param str iso  Coded string 
 * @return
 * @author zongf
 * @date 2019 Year 1 Month 8 Day - Afternoon 3:55:29
 */
private String iso2Utf8(String str) {
 if(null == str) return null;
 
 try {
  return new String(str.getBytes("ISO-8859-1"), "UTF-8");
 } catch (UnsupportedEncodingException e) {
  e.printStackTrace();
 }
 return null;
}

4. Properties file

The author created the maven project and used the junit unit test, so the author's configuration file is stored in the src/test/resources directory.

jdbc.properties


jdbc.username= Zhang 3
jdbc.password=123456

jdbc_zh.properties


jdbc.username= Zhang 3
jdbc.password=123456

jdbc_en.properties


jdbc.username=zhangsan
jdbc.password=123456

5. Practical recommendation

The author believes that a well-designed attribute configuration class should be a constant class, which needs to conform to at least two design principles:

The property 1 denier setting cannot be dynamically modified, and the modification method cannot be called even in the compilation environment.

Can be accessed directly through class attributes, without accessing through class objects

Automatically assemble properties without having to manually parse familiar files (available in S140EN with self-annotations or custom annotations)


public class JdbcProperty { 
 /**  User name  */
 public static final String username;
 
 /**  User password  */
 public static final String password;
 
 //  In Spring In application , Automatic assembly with annotations or custom annotations , The author here only aims at 1 Like java Application 
 static {
  
  //  Load properties file 
  ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
  
  //  Initialize properties 
  username = resourceBundle.getString("jdbc.username");
  password = resourceBundle.getString("jdbc.password");  
 }
}

Related articles: