如何在Java中将JSON的JSON转换为JSON数组?

huangapple go评论110阅读模式
英文:

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&#39;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(&quot;http://ddragon.leagueoflegends.com/cdn/13.15.1/data/en_US/champion.json&quot;))
                    .header(&quot;accept&quot;, &quot;application/json&quot;)
                    .build();

            var responseFuture = client.sendAsync(request, new JsonBodyHandler&lt;&gt;(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(&quot;data&quot;) JsonNode championsData) {
    this.championsData = championsData;
}

}


I&#39;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(&quot;id&quot;) String id,
            @JsonProperty(&quot;name&quot;) String name,
            @JsonProperty(&quot;blurb&quot;) String blurb,
            @JsonProperty(&quot;image&quot;) List image,
            @JsonProperty(&quot;title&quot;) 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&#39;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&#39;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&lt;String,Object&gt; content = mapper.readValue(new File(fileName), Map.class);

String host = &quot;mongodb://your_connection_uri&quot;;
MongoClient client = MongoClients.create(host);
MongoDatabase db = client.getDatabase(&quot;testX&quot;);
MongoCollection&lt;Document&gt; coll = db.getCollection(&quot;foo&quot;, Document.class);

java.util.Map data = (java.util.Map) content.get(&quot;data&quot;);
      
data.forEach(
             (key, value)
             -&gt; {
                 //  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[]{&quot;name&quot;,&quot;blurb&quot;,&quot;title&quot;,&quot;image&quot;}) {
                     dd.put(k2, m.get(k2));
                 }
                 coll.insertOne(dd);
             });

huangapple
  • 本文由 发表于 2023年8月4日 20:52:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76836099.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定