0

I'm trying to get info from https://prices.runescape.wiki/api/v1/osrs/latest

 HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                    .GET()
                    .uri(URI.create("https://prices.runescape.wiki/api/v1/osrs/latest"))
                    .build();
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            ObjectMapper mapper = new ObjectMapper();
            JsonNode json = mapper.readTree(response.body());
            JsonNode data = json.get("data");
            List<Data> items = new ArrayList<>();
            data.forEach(item -> {
                Data d = new Data(
                        item.get("high").asInt(),
                        item.get("highTime").asInt(),
                        item.get("low").asInt(),
                        item.get("lowTime").asInt()
                );
                items.add(d);

            });

Problem is the object is the itemID. So if I want the item id 6. I can't do it since it's not an attribute of the object.

"2":{"high":164,"highTime":1672078170,"low":160,"lowTime":1672078164} ``

"2" is the itemID and the object.

Below is when I loop through the arraylist and print it out

Data{high=157, highTime=1672071161, low=150, lowTime=1672071151}
Data{high=187987, highTime=1672071066, low=182005, lowTime=1672070881}
Data{high=189903, highTime=1672071052, low=186820, lowTime=1672070884}
Data{high=190000, highTime=1672070957, low=184882, lowTime=1672070984}
9
  • Can you please rephrase this sentence "Problem is the object is the itemID. So if I want the item id 6. I can't do it since even the class name returns and I can only get index"? There's no property itemID in your sample data. Commented Dec 26, 2022 at 18:08
  • In the Rest API. The itemID is the object. ``` "2":{"high":164,"highTime":1672078170,"low":160,"lowTime":1672078164} ``` 2 is the object. So how would I be able to get it since it isn't a attribute? Commented Dec 26, 2022 at 18:10
  • It looks rather like a Map "2":{ ... } (or you have an JSON-object with a property "2"). And there's no itemID that you've mentioned twice. Commented Dec 26, 2022 at 18:16
  • Also, please, don't post clarifications in the comments, update the question. Commented Dec 26, 2022 at 18:16
  • "So how would I be able to get it since it isn't a attribute?" - as I've said "2":{ ... } looks like a Map<Integer,Data>, can you share the rest JSON (for now it's unclear how to access it from the enclosing JSON-object) ? Commented Dec 26, 2022 at 18:21

1 Answer 1

2

Your JSON has the following structure:

{
   "data":{
      "2":{ ... },
      "6":{ ... },
      "8":{ ... },
      "10":{ ... },
      "12":{ ... }
      ...
   }
}

And property "data" is associated not with an object, or a List<Data>, but with a Map<Integer,Data> (or Map<String,Data>.

There are several ways how you can parse:

  • You can define an object with a single property Map<Integer,Data> data.
public static class DataWrapper {
    private Map<Integer, Data1> data;
    
    // getters, setters
}

Usage example:

String json = """
            {
               "data":{ ... }
            }
            """;

ObjectMapper mapper12 = new ObjectMapper();
        
DataWrapper dataWrapper = mapper12.readValue(json12, DataWrapper.class);
Map<Integer, Data1> dataMap = dataWrapper.getData();
    
System.out.println("item 6: " + dataMap.get(6));
  • Another approach would be to create a JsonNode by parsing the given JSON, access the node mapped to the property "data" and parse it as a Map using ObjectReader and its method ObjectReader.readValue(). To generate ObjectReader we can make use of the method ObjectMapper.readerFor() which expects a TypeReference.

That's how the second approach might be implemented:

String json = """
            {
               "data":{ ... }
            }
            """;
        
ObjectMapper mapper = new ObjectMapper();
JsonNode tree = mapper.readTree(json);
        
ObjectReader reader = mapper.readerFor(new TypeReference<Map<Integer, Data>>() {});
Map<Integer, Data> itemsMap = reader.readValue(tree.get("data"));
    
System.out.println("item 6: " + itemsMap.get(6));

Output:

item 6: Data{high=195500, highTime=1672079035, low=182009, lowTime=1672078518}
Sign up to request clarification or add additional context in comments.

4 Comments

The output is not what I need. For example, If I ONLY WANT object 2, 56, 113, and 125. How would you get the high, highTime, low, lowTime for those only
@rairai See the update, you can access the required object using a Map.
k thanks it works. I would word it better, but how would you have worded the question?
@rairai I've added an example for the first approach (it's shorter, but requires defining a separate class). "how would you have worded the question?" - when you were mentioning "id 6" and then providing the map entry with the key 2 it looked a bit misleading for me, maybe it was worth to emphasize that you need the individual items (for instance like you've said in the comment "If I only want object 2, 56, 113, and 125"). Never mind, the key take away is that JSON-structure in Java can be represented as Map.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.