Перейти к основному содержимому

Начало работы со свойствами Java

· 5 мин. чтения

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 .