本文以瑞士奶酪为例介绍了如何从头把 JSON 文件映射成 Java 枚举。


最近为一个回头客新做了一个 Java 项目。第一个任务用 JSON 属性文件实现程序全局配置。


功能完成之后发现这个解决方案用起来很方便,打算写一篇博客分享。由于之前没有写过任何 Java 技术博客,发现这个过程相当挑战而且趣味。


0. 引言


本文涵盖以下内容:


  1. 创建新项目

  2. 读取 JSON 文件和属性

  3. 创建枚举

  4. 把属性映射为泛型枚举


注意: 如果你已经有了一个项目,可以跳过接下来的第一章。同样,如果不使用 Maven 也可以跳过,按照自己的设置添加要使用的开发库。


1. 创建新项目


首先,用 Maven starter 工具新建项目。在终端中运行以下命令:


$ 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


2. 读取 JSON 文件和属性


起初,我自己实现了一个快速解决方案,但是对结果一点也不满意。这就是为什么试着在网上寻找一个现成的解决方案,结果发现了神奇的 com.typesafe.config 开源三方库。


它提供了读取 JSON 文件和访问属性需要的所有功能,没有依赖而且兼容 Java 8。


至少这一次,用谷歌搜索是一个绝妙的主意。


使用前,需要在到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>


build 配置完毕,现在可以进入下一步,创建 JSON 属性文件。


默认情况下,configuration 开发库会把名为 application.json的文件作为属性源文件加载。


简单起见,在新文件夹 src/resources/ 中用默认文件名创建配置,包含以下 JSON 内容:

{
 "swiss": {
   "cheese": "gruyere"
 }
}


一切设置妥当,开始编码。


修改程序,在src/main/java/com/jsontoenum/app 文件夹中的App.java 中初始化并从 JSON 文件加载属性,然后输出我们喜爱的 cheese名称。


package com.jsontoenum.app;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
public class App {
  public static void main(String[] args) {
      // 加载并初始化 configuration 开发库
     final Config conf = ConfigFactory.load();
     // 读取 JSON 属性值
     final String cheese = conf.getString("swiss.cheese");
     System.out.println(String.format("I like %s