Пошаговое руководство на примере швейцарского сыра

Недавно я начал новый Java-проект для вернувшегося клиента. Одной из первых моих задач было реализовать новую функцию с целью сделать приложение глобально настраиваемым с помощью файла свойств JSON.
Получившееся решение мне показалось относительно удобным, и я подумал, что поделюсь им в новом сообщении в блоге. Более того, поскольку я до сих пор не писал никаких сообщений в блогах о Java, мне это показалось довольно сложным и интересным.
Вступление
В этой статье мы собираемся:
- Создайте новый проект.
- Прочтите файл и свойство JSON.
- Создайте перечисление.
- Сопоставьте свойства с общим перечислением.
Примечание: если у вас уже есть проект, вы, очевидно, можете пропустить первую главу, в которой цель состоит в создании проекта. Точно так же, если вы не хотите использовать Maven, пропустите и его и включите библиотеку, которую мы собираемся использовать, как того требует ваша установка.
Создать новый проект
Для начала создадим новый проект, используя стартовый набор Maven. Для этого выполните в терминале следующую команду:
$ mvn archetype:generate -DgroupId=com.jsontoenum.app -DartifactId=json-to-enum -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
Если все прошло хорошо, теперь вы можете перейти в каталог, чтобы скомпилировать проект без ошибок:
$ cd json-to-enum/ && mvn package
Прочтите файл и свойство JSON
Сначала я реализовал быстрое индивидуальное решение, но результат меня совсем не удовлетворил. Вот почему я попытался найти готовое решение в Интернете и нашел невероятную библиотеку с открытым исходным кодом com.typesafe.config.
Он использует всю работу по чтению файлов JSON и доступу к их свойствам, не имеет зависимостей и даже совместим с Java 8.
По крайней мере, на этот раз поиск решения в Google был отличной идеей.
Чтобы использовать библиотеку, давайте добавим новую зависимость этой библиотеки в наш pom.xml:
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.3.4</version>
</dependency>
Более того, мы также должны добавить следующие <resources/> и <plugins/> цели в наш <build/>, чтобы иметь возможность загрузить файл JSON (который мы собираемся создать) и упаковать зависимость, на которую мы только что ссылались, в нашем файле JAR.
<resources>
<resource>
<directory>src/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Наша сборка наконец-то настроена. Теперь мы можем перейти к следующему шагу и создать наш файл свойств JSON.
По умолчанию библиотека конфигурации попытается загрузить файл с именем application.json в качестве источника свойств.
Поэтому давайте будем простыми и будем использовать это предопределенное имя для создания этого нового файла в новой папке src/resources/ со следующим содержимым JSON:
{
"swiss": {
"cheese": "gruyere"
}
}
Все настроено, время писать код.
Мы могли бы изменить наше приложение (App.java в папке src/main/java/com/jsontoenum/app) для инициализации и загрузки свойств из файла JSON и распечатать название нашего любимого вида сыра.
package com.jsontoenum.app;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
public class App {
public static void main(String[] args) {
// Load and init the configuration library
final Config conf = ConfigFactory.load();
// Get the value of the JSON property
final String cheese = conf.getString("swiss.cheese");
System.out.println(String.format("I like %s 🧀", cheese));
}
}
Давайте скомпилируем все и запустим наш проект, используя следующую командную строку в терминале, чтобы опробовать нашу реализацию:
$ mvn package && java -cp target/json-to-enum-1.0-SNAPSHOT.jar com.jsontoenum.app.App
Если все прошло нормально, в конце трассировки стека в выводе консоли должно отображаться следующее:
[INFO] ------------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------- [INFO] Total time: 2.179 s [INFO] Finished at: 2019-08-16T15:04:35+02:00 [INFO] ------------------------------------------------------------- I like gruyere 🧀
Создать Enum
Даже если было уже круто иметь возможность читать свойства JSON, при разработке назначенной мне функции я быстро понял, что возможность сопоставить свойства с enum будет как бы обязательной, если приложение должно вести себя по-другому соответственно.
Кроме того, Швейцария производит более одного вида сыра.
Поэтому в качестве следующего шага мы могли бы создать перечисление в папке src/main/java/com/jsontoenum/app/, в котором можно было бы перечислить пару сыров из франкоязычной части страны:
package com.jsontoenum.app;
public enum Cheese {
GRUYERE,
TETE_DE_MOINE,
CHAUX_DABEL,
RACLETTE,
VACHERIN,
TOMME
}
Сопоставьте свойства с общим перечислением
В этой статье мы используем сыр в демонстрационных целях, но очевидно, что Швейцария экспортирует многие другие продукты, такие как шоколад и часы.
Точно так же приложение, над которым я работаю, не содержит только одного перечисления. Вот почему мы не только добавляем метод для синтаксического анализа свойств одного типа перечисления, но и объявляем его универсальным в нашем приложении (App.java).
private static <E extends Enum<E>> E getEnumProperty(final Config conf, final String key, final Class<E> myClass) {
// If no config loaded
if (conf == null) {
return null;
}
// If the config doesn't contains the key
if (!conf.hasPath(key)) {
return null;
}
// As previously, load the key value
final String keyValue = conf.getString(key);
// Does the property has a value
if (keyValue == null || keyValue.isEmpty()) {
return null;
}
// Map the property to the ENUM
return Enum.valueOf(myClass, keyValue.toUpperCase());
}
Наконец, для заключительного теста давайте усовершенствуем наш main метод, загрузив перечисление и проверив его, чтобы показать, является ли сыр нашим любимым сыром или нет:
public static void main(String[] args) {
// Load and init the configuration library
final Config conf = ConfigFactory.load();
// Get the value of the JSON property
final Cheese cheese =
getEnumProperty(conf, "swiss.cheese", Cheese.class);
if (Cheese.GRUYERE.equals(cheese)) {
System.out.println(String.format("I really like %s 🧀", cheese));
} else {
System.out.println(String.format("%s is ok", cheese));
}
}
Вуаля, вот и все, не больше и не меньше.
Вы можете попробовать запустить наш проект, используя предыдущую командную строку, и если все пойдет по плану, результат должен выглядеть так:
[INFO] ------------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------- [INFO] Total time: 2.437 s [INFO] Finished at: 2019-08-16T15:43:42+02:00 [INFO] ------------------------------------------------------------- I really like GRUYERE 🧀
Вишня на торте 🍒🎂
Если вы хотите избежать хлопот с созданием собственного проекта и копированием приведенного выше кода, я опубликовал проект в Интернете, будь моим гостем.
$ git clone https://github.com/peterpeterparker/json-to-enum.git
До бесконечности и дальше 🚀
Дэйвид