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.
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.
// 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);
});