1. Обзор
Большинству приложений Java в какой-то момент необходимо использовать свойства, как правило, для хранения простых параметров в виде пар ключ-значение вне скомпилированного кода.
Таким образом, язык имеет первоклассную поддержку свойств — java.util.Properties
— служебный класс, предназначенный для обработки файлов конфигурации такого типа.
Это то, на чем мы сосредоточимся в этой статье.
2. Загрузка свойств
2.1. Из файлов свойств
Начнем с примера загрузки пар ключ-значение из файлов свойств; мы загружаем два файла, доступных в нашем пути к классам:
приложение.Свойства:
version=1.0
name=TestApp
date=2016-11-12
И каталог
:
c1=files
c2=images
c3=videos
Обратите внимание, что несмотря на то, что файлы свойств рекомендуется использовать с суффиксом « .properties
», это не обязательно.
Теперь мы можем очень просто загрузить их в экземпляр Properties :
String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String appConfigPath = rootPath + "app.properties";
String catalogConfigPath = rootPath + "catalog";
Properties appProps = new Properties();
appProps.load(new FileInputStream(appConfigPath));
Properties catalogProps = new Properties();
catalogProps.load(new FileInputStream(catalogConfigPath));
String appVersion = appProps.getProperty("version");
assertEquals("1.0", appVersion);
assertEquals("files", catalogProps.getProperty("c1"));
Пока содержимое файла соответствует требованиям к формату файла свойств, оно может быть правильно проанализировано классом свойств .
Ниже приведены дополнительные сведения о формате файла свойств .
2.2. Загрузка из XML-файлов
Помимо файлов свойств, класс Properties
также может загружать XML-файлы, которые соответствуют конкретным спецификациям DTD.
Вот пример загрузки пар ключ-значение из XML-файла — icons.xml
:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>xml example</comment>
<entry key="fileIcon">icon1.jpg</entry>
<entry key="imageIcon">icon2.jpg</entry>
<entry key="videoIcon">icon3.jpg</entry>
</properties>
Теперь давайте загрузим его:
String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String iconConfigPath = rootPath + "icons.xml";
Properties iconProps = new Properties();
iconProps.loadFromXML(new FileInputStream(iconConfigPath));
assertEquals("icon1.jpg", iconProps.getProperty("fileIcon"));
3. Получить свойства
Мы можем использовать getProperty(String key)
и getProperty(String key, String defaultValue)
для получения значения по его ключу.
Если пара ключ-значение существует, оба метода вернут соответствующее значение. Но если такой пары ключ-значение нет, первый вернет null, а второй вместо этого вернет defaultValue
.
Пример кода:
String appVersion = appProps.getProperty("version");
String appName = appProps.getProperty("name", "defaultName");
String appGroup = appProps.getProperty("group", "foreach");
String appDownloadAddr = appProps.getProperty("downloadAddr");
assertEquals("1.0", appVersion);
assertEquals("TestApp", appName);
assertEquals("foreach", appGroup);
assertNull(appDownloadAddr);
Обратите внимание, что хотя класс Properties
наследует метод get() от класса
Hashtable
, я бы не рекомендовал вам использовать его для получения значения. Потому что его метод get()
вернет значение Object
, которое может быть приведено только к String
, а метод getProperty()
уже правильно обрабатывает необработанное значение Object .
Код ниже вызовет исключение
:
float appVerFloat = (float) appProps.get("version");
4. Установите свойства
Мы можем использовать метод setProperty()
для обновления существующей пары ключ-значение или добавления новой пары ключ-значение.
Пример кода:
appProps.setProperty("name", "NewAppName"); // update an old value
appProps.setProperty("downloadAddr", "www.foreach.com/downloads"); // add new key-value pair
String newAppName = appProps.getProperty("name");
assertEquals("NewAppName", newAppName);
String newAppDownloadAddr = appProps.getProperty("downloadAddr");
assertEquals("www.foreach.com/downloads", newAppDownloadAddr);
Обратите внимание, что хотя класс Properties
наследует метод put()
и метод putAll()
от класса Hashtable
, я бы не рекомендовал вам использовать их по той же причине, что и для метода get() : в
Properties
можно использовать только строковые
значения . ``
Приведенный ниже код не будет работать так, как вы хотите, когда вы используете getProperty()
для получения его значения, он вернет null
:
appProps.put("version", 2);
5. Удалить свойства
Если вы хотите удалить пару ключ-значение, вы можете использовать метод remove() .
Пример кода:
String versionBeforeRemoval = appProps.getProperty("version");
assertEquals("1.0", versionBeforeRemoval);
appProps.remove("version");
String versionAfterRemoval = appProps.getProperty("version");
assertNull(versionAfterRemoval);
6. Магазин
6.1. Сохранить в файлах свойств
`Класс
Properties предоставляет метод
store()` для вывода пар ключ-значение.
Пример кода:
String newAppConfigPropertiesFile = rootPath + "newApp.properties";
appProps.store(new FileWriter(newAppConfigPropertiesFile), "store to properties file");
Второй параметр для комментария. Если вы не хотите писать комментарий, просто используйте для него null.
6.2. Сохранить в XML-файлы
`Класс
свойств также предоставляет метод
storeToXML()` для вывода пар ключ-значение в формате XML.
Пример кода:
String newAppConfigXmlFile = rootPath + "newApp.xml";
appProps.storeToXML(new FileOutputStream(newAppConfigXmlFile), "store to xml file");
Второй параметр такой же, как в методе store() .
7. Другие общие операции
Класс свойств
также предоставляет некоторые другие методы для работы со свойствами.
Пример кода:
appProps.list(System.out); // list all key-value pairs
Enumeration<Object> valueEnumeration = appProps.elements();
while (valueEnumeration.hasMoreElements()) {
System.out.println(valueEnumeration.nextElement());
}
Enumeration<Object> keyEnumeration = appProps.keys();
while (keyEnumeration.hasMoreElements()) {
System.out.println(keyEnumeration.nextElement());
}
int size = appProps.size();
assertEquals(3, size);
8. Список свойств по умолчанию
Объект Properties
может содержать другой объект Properties
в качестве списка свойств по умолчанию. Список свойств по умолчанию будет искаться, если ключ свойства не найден в исходном списке.
Помимо « app.properties
», у нас есть еще один файл — « default.properties
» — в нашем пути к классам:
default.properties:
site=www.google.com
name=DefaultAppName
topic=Properties
category=core-java
Пример кода:
String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String defaultConfigPath = rootPath + "default.properties";
Properties defaultProps = new Properties();
defaultProps.load(new FileInputStream(defaultConfigPath));
String appConfigPath = rootPath + "app.properties";
Properties appProps = new Properties(defaultProps);
appProps.load(new FileInputStream(appConfigPath));
assertEquals("1.0", appVersion);
assertEquals("TestApp", appName);
assertEquals("www.google.com", defaultSite);
9. Свойства и кодировка
По умолчанию файлы свойств должны иметь кодировку ISO-8859-1 (Latin-1), поэтому свойства с символами, отличными от ISO-8859-1, обычно не должны использоваться.
Мы можем обойти это ограничение с помощью таких инструментов, как JDK native2ascii или явной кодировки файлов, если это необходимо.
Для файлов XML методы loadFromXML()
и storeToXML()
по умолчанию используют кодировку символов UTF-8.
Однако при чтении XML-файла, закодированного по-другому, мы можем указать это в объявлении DOCTYPE
; запись также достаточно гибкая — мы можем указать кодировку в третьем параметре API storeToXML()
.
10. Заключение
В этой статье мы обсудили базовое использование класса свойств
, в том числе то, как использовать свойства
для загрузки и хранения пар ключ-значение как в свойствах, так и в формате XML, как работать с парами ключ-значение в объекте свойств
, например извлекать значения, обновлять значения . , получить его размер и как использовать список по умолчанию для объекта Properties .
Полный исходный код примера доступен в этом проекте GitHub .