一、代码展示
1、Apollo中待解析的JSON
"items": [
{
"date": "2023-11-22",
"title": "2.0版本上线啦~",
"newFeatures": [
"自助分析助手",
"统一分析增加编辑功能"
],
"optimizations": [
"支持业务数据接入",
"统一分析增加编辑功能"
]
},
{
"date": "2023-11-23",
"title": "2.0版本上线啦~",
"newFeatures": [
"自助分析助手",
"统一分析增加编辑功能"
],
"optimizations": [
"支持业务数据接入",
"统一分析增加编辑功能"
]
}
]
2、解析成的类
package com.longfor.idata.server.dto.statement.response;
import lombok.Data;
import java.util.List;
/**
* 公告栏信息
*/
@Data
public class ItemConfig {
public List<Item> items;
@Data
public static class Item {
private String date;
private String title;
private List<String> newFeatures;
private List<String> optimizations;
}
}
3、解析过程
@Value("${items-config}")
private String itemConfig;
@Override
public ItemConfig getAnnouncementList() {
ItemConfig result = new ItemConfig();
try {
// 使用 JsonReader 解析 JSON 字符串
JsonReader jsonReader = Json.createReader(new StringReader("{" + itemConfig + "}"));
JsonObject jsonObject = jsonReader.readObject();
// 获取 "items" 字段对应的 JsonArray
JsonArray itemsArray = jsonObject.getJsonArray("items");
// 手动解析数组元素
List<ItemConfig.Item> itemList = new ArrayList<>();
for (int i = 0; i < itemsArray.size(); i++) {
JsonObject itemObject = itemsArray.getJsonObject(i);
ItemConfig.Item item = new ItemConfig.Item();
item.setDate(itemObject.getString("date"));
item.setTitle(itemObject.getString("title"));
JsonArray newFeaturesArray = itemObject.getJsonArray("newFeatures");
List<String> newFeatures = new ArrayList<>();
for (int j = 0; j < newFeaturesArray.size(); j++) {
newFeatures.add(newFeaturesArray.getString(j));
}
item.setNewFeatures(newFeatures);
JsonArray optimizationsArray = itemObject.getJsonArray("optimizations");
List<String> optimizations = new ArrayList<>();
for (int j = 0; j < optimizationsArray.size(); j++) {
optimizations.add(optimizationsArray.getString(j));
}
item.setOptimizations(optimizations);
itemList.add(item);
}
// 构建最终的 ItemConfig 对象
result = new ItemConfig();
result.setItems(itemList);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
二、关键方法
这段代码主要涉及以下几个关键知识点:
1、@Value(“${items-config}”):这是使用Spring框架的@Value注解,用于将配置文件中的items-config属性的值注入到类成员变量itemConfig中。
2、JsonReader 和 JsonObject:这两个类是Java JSON Processing API(javax.json)提供的,用于解析JSON数据。JsonReader从输入流中读取JSON数据,而JsonObject表示JSON对象。
3、解析JSON数组元素:通过JsonArray和JsonObject来解析JSON数组元素。在这个例子中,itemsArray表示JSON数组,通过循环遍历数组元素,并使用getJsonObject(i)方法获取每个元素的JsonObject。
4、手动解析数组元素:在循环中,通过itemObject.getString(“date”)等方法手动获取JSON对象中的字段值,然后构建Item对象,并添加到itemList中。
5、构建最终的对象:通过手动解析得到的数据,构建ItemConfig对象,设置其items属性为解析得到的itemList。
三、解惑
1、为什么ConfigurationProperties注解不行?
那有些同学要问了,这种情况不可以使用ConfigurationProperties(prefi=“”)进行吗?
@ConfigurationProperties 主要用于将配置文件中的属性映射到 Java 对象中,支持复杂对象的映射,但是在这个场景中,由于 JSON 字符串的结构并不是简单的 key-value 形式,而是包含了数组和嵌套结构,不太适合直接使用 @ConfigurationProperties 注解。
@ConfigurationProperties 适用于映射类似 application.properties 或 application.yml 这样的简单配置文件,其中属性是扁平的键值对结构。
所以,使用 @ConfigurationProperties 可能不太合适,因为这需要一个扁平的属性结构。相反,使用了手动解析 JSON 的方式,这在处理复杂结构时可能更为直观。
如果你的 JSON 结构相对简单,而且你想要将其映射到配置文件中,那么 @ConfigurationProperties 是一个不错的选择。但是对于这种复杂的结构,手动解析可能更加灵活和清晰。
2、扁平的键值对结构是什么?
当提到“其中属性是扁平的键值对结构”时,这表示属性具有简单的键-值对结构,没有嵌套结构或复杂的层次关系。每个属性都有一个单一级别,键是简单的,不嵌套在其他键内。
举例说明:
考虑一个使用属性格式(application.properties 或 application.yml)的配置文件,其中包含扁平的键值对:
# 以属性格式为例
app.name=MyApp
app.version=1.0
app.debug=true
在这个例子中,每个属性(app.name、app.version、app.debug)都具有扁平结构。它们不会相互嵌套,键直接表示属性名称。
同样,在 YAML 格式中:
# 以 YAML 格式为例
app:
name: MyApp
version: 1.0
debug: true
在 YAML 中,结构在视觉上暗示层次关系,但键仍然是扁平的(app.name、app.version、app.debug),属性没有深层嵌套。
总结:
这段代码使用了Java JSON Processing API(javax.json)来解析JSON数据。另外,对于异常处理,代码使用了简单的try-catch块来捕获异常并打印堆栈信息。在实际应用中,可能需要根据具体情况进行更详细的异常处理。