英文:
How to convert JSON of JSONs to array of JSONs in Java?
问题
I've translated the code-related content for you:
我一直在我的个人项目中遇到一些问题。
我使用以下代码从以下网址提取数据字段:http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json:
```java
import DataHandlers.ChampionsJson;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.util.concurrent.ExecutionException;
public class ChampionsDataScheduler extends Thread{
@Override
public void run(){
while(true){
try {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(
URI.create("http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json"))
.header("accept", "application/json")
.build();
var responseFuture = client.sendAsync(request, new JsonBodyHandler<>(ChampionsJson.class));
var response = responseFuture.get();
var data = response.body().get().championsData;
System.out.println(data);
Thread.sleep(1000);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
}
使用这个类:
package DataHandlers;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChampionsJson {
public final JsonNode championsData;
@JsonIgnoreProperties(ignoreUnknown = true)
public ChampionsJson(@JsonProperty("data") JsonNode championsData) {
this.championsData = championsData;
}
}
我尝试将接收到的JSON中的每个冠军(每个值)注入到以下对象中并创建一个数组:
package DataHandlers;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChampionsData {
public final String id;
public final String name;
public final String blurb;
public final List image;
public final String title;
@JsonIgnoreProperties(ignoreUnknown = true)
public ChampionsData(@JsonProperty("id") String id,
@JsonProperty("name") String name,
@JsonProperty("blurb") String blurb,
@JsonProperty("image") List image,
@JsonProperty("title") String title) {
this.id = id;
this.name = name;
this.title = title;
this.blurb = blurb;
this.image = image;
}
}
但是,我无法成功,因为我将JSON作为JSON字符串获得,并且尚未找到正确解析它的方法。
有什么想法吗?或者也许有更好的方法吗?
如果您想了解更多上下文,我的最终目标是将ChampionsData对象数组转换为morphia对象数组并将其插入到Mongo中。
Please note that I've only translated the code-related content and removed any non-essential information. If you have any specific questions or need further assistance with the code, please let me know.
<details>
<summary>英文:</summary>
I've been running into some issues on a personal project of mine.
I fetch the data field from the url: http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json with the following code:
import DataHandlers.ChampionsJson;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.util.concurrent.ExecutionException;
public class ChampionsDataScheduler extends Thread{
@Override
public void run(){
while(true){
try {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(
URI.create("http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json"))
.header("accept", "application/json")
.build();
var responseFuture = client.sendAsync(request, new JsonBodyHandler<>(ChampionsJson.class));
var response = responseFuture.get();
var data = response.body().get().championsData;
System.out.println(data);
Thread.sleep(1000);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
}
Using this class:
package DataHandlers;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChampionsJson {
public final JsonNode championsData;
@JsonIgnoreProperties(ignoreUnknown = true)
public ChampionsJson(@JsonProperty("data") JsonNode championsData) {
this.championsData = championsData;
}
}
I'm trying to inject each champion (each value in the received json) to the following object and create an array of it:
package DataHandlers;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChampionsData {
public final String id;
public final String name;
public final String blurb;
public final List image;
public final String title;
@JsonIgnoreProperties(ignoreUnknown = true)
public ChampionsData(@JsonProperty("id") String id,
@JsonProperty("name") String name,
@JsonProperty("blurb") String blurb,
@JsonProperty("image") List image,
@JsonProperty("title") String title) {
this.id = id;
this.name = name;
this.title = title;
this.blurb = blurb;
this.image = image;
}
}
but I fail to do so because I get the JSON as a string of JSONs, and I haven't figured out a way to parse it correctly.
Any idea how to do that? Is there maybe a better way to do so?
If you want to get more context on it, my final goal is to convert the ChampionsData object array to a morphia object array and insert it into Mongo.
</details>
# 答案1
**得分**: 1
以下是您要翻译的内容:
"数据位于`http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json`,是一个包含单个键`data`的单个JSON对象。 `data`是一个包含大约164个子字段的对象,每个子字段似乎都是冠军的名称。没有数组;您必须迭代`data`字段。
如果目标是将此数据插入MongoDB,那么我建议将每个冠军作为单独的文档。子字段携带了许多标识信息,如`name`、`key`和`id`,所以让我们保留它们,并让MongoDB客户端驱动程序自动生成`_id`。
OQ代码尝试将`image`存储为列表。JSON中的`image`不是列表;它是一个对象(一个子结构)。在下面的代码中,我们将整个`image`对象复制到要插入的文档中。"
请注意,我已经删除了您的要求,仅提供了翻译的部分内容。
<details>
<summary>英文:</summary>
The data at `http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json` is a single JSON object with a single key `data`. `data` is an object with approx 164 subfields, each of which appears to be the name of a champion. There are no arrays; you must iterate over the `data` field.
If the goal is to insert this data into MongoDB, then I recommend making each champion a separate document. The subfields carry a lot of identifying information like `name`,`key`, and `id` so let's keep that and let MongoDB client side driver invent the `_id`.
The OQ code attempts to take `image` and store it as a list. `image` from the JSON is not a list; it is an object (a substructure). In the code below, we will copy over the whole `image` object into the Document to be inserted.
```java
// The OQ code to fetch the JSON is directionally correct. It results in
// the JSON string being stored in variable `data` and sort of trapped in
// the thread but the approach is fine. The details of organizing the
// code to schedule and fetch the data are not relevant to the question.
ObjectMapper mapper = new ObjectMapper();
// OP has JSON string somewhere in the mix of @championsData; not sure
// how it is wired together but the goal is the same: to parse the
// JSON into a Java Map object using mapper. As a proxy, we show
// readValue() from a file here:
Map<String,Object> content = mapper.readValue(new File(fileName), Map.class);
String host = "mongodb://your_connection_uri";
MongoClient client = MongoClients.create(host);
MongoDatabase db = client.getDatabase("testX");
MongoCollection<Document> coll = db.getCollection("foo", Document.class);
java.util.Map data = (java.util.Map) content.get("data");
data.forEach(
(key, value)
-> {
// Use this to deep copy all fields for each champion:
//Document dd = new Document((Map)value);
// .. or this to only pick up select items:
Document dd = new Document();
Map m = (Map)value;
for(String k2 : new String[]{"name","blurb","title","image"}) {
dd.put(k2, m.get(k2));
}
coll.insertOne(dd);
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论