0

I have the following code which I use to download a JSON file from a URL:

static void getPost() throws Exception {
        String webPage = "https://www.reddit.com/r/arabfunny/top.json?limit=100";

        URL url = new URL(webPage);
        URLConnection request = url.openConnection();
        request.setRequestProperty("Content-Type", "application/json; utf-8");
        request.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");

        JsonParser jp = new JsonParser();
        JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
        JsonObject rootobj = root.getAsJsonObject();
        String imageURL = rootobj.get("data").toString();
        System.out.println(imageURL);
    }

This correctly gets the code but I'm having trouble getting data past the first level, I can use .get("data") and that works as expected but I cannot do .get("data").get("children").

The JSON file can be found here.

Here is the JSON prettyfied.

enter image description here

I want to get a random children where I don't know the number of children. Something like rootobj.get("data").get("children").get(RANDOM).toString();

EDIT:

I really just need a simple solution to get a few parameters from a random children.

enter image description here

I need to get JSON -> data -> children[random item] -> data -> subreddrit (or other final field)

Can anyone show me a basic working example that would give me any final value which I can then modify?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Luke Prior
  • 885
  • 2
  • 11
  • 34

2 Answers2

1

Use Jackson from maven

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.2</version>
</dependency>
ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = objectMapper.readValue(<OUTPUT_JSON>,JsonNode.class);
rootobj.get("data").get("children")[INDEX].get(RANDOM).asText();
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Santosh b
  • 729
  • 1
  • 8
  • 19
1

For me it is easier to define your return object using Pojo and use Gson to deserialize it.

Maven dependency

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.3</version>
</dependency>

Then define your Result Pojo

public class MyResult{

   public Data data;

   //getter

}

//Data POJO

public class Data{

      public String modhash;
      public Integer dist;
      public List<Children> children; //define your object
      public String after;
      public String before;

      //getters
      
   }

Children POJO

public class Children{
     private String kind;
     private String data; //You can define another Data Object if you want to

     //getters
     
     //toString() method.
}

NOTE: Make sure that JSON field names are exactly the same as POJO field names.

To convert Json string to object:

//get Json String from request : START
InputStream inputStream = request.getInputStream();
       
InputStreamReader isReader = new InputStreamReader(inputStream);
//Creating a BufferedReader object
BufferedReader reader = new BufferedReader(isReader);
StringBuffer sb = new StringBuffer();
String str;
while((str = reader.readLine())!= null){
   sb.append(str);
}
       
String jsonString = sb.toString();
//get Json String from request : END
        
MyResult result = new Gson().fromJson(jsonString,MyResult.class)
result.getData().getChildren()
    .get(0) //get index 0 from list
    .toString();

If you do not want to create too many layer of Pojos, create your own JsonAdapter.

I haven't tested this so there might be some syntax error.

Also you can look at JsonPath library for parsing json file using dot notation.

NothingBox
  • 345
  • 5
  • 15
  • I'm not sure how this works, are you able to show me a solution to achieve what I've laid out in my EDIT? @NothingBox – Luke Prior Aug 09 '20 at 04:59
  • "Also you can look at JsonPath library for parsing json file using dot notation." I had a quick look and this seems like what I want I have figured out the JSONPath Syntax to be "$.data.children[0].data.subreddit" do you know how I can implement this? – Luke Prior Aug 09 '20 at 05:08
  • I haven't used JsonPath but perhaps this tutorial can help. https://www.baeldung.com/guide-to-jayway-jsonpath – NothingBox Aug 09 '20 at 05:16
  • How can i download the webpage as a string as JsonPath works with that but not a gson object? – Luke Prior Aug 09 '20 at 05:18
  • I just realized the request.getContent() doesn't actually get the actual result. I have updated my answer, please see code block `get Json String from request` to get the response as String. Also, this solution assumes that response code is 200 (Success), you should also handle other response codes. See https://stackoverflow.com/questions/25011927/how-to-get-response-body-using-httpurlconnection-when-code-other-than-2xx-is-re/25012003 – NothingBox Aug 09 '20 at 05:36
  • 1
    I just did JsonParser jp = new JsonParser(); JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); String testing1 = root.toString(); – Luke Prior Aug 09 '20 at 05:39
  • Yeah, that is simpler solution :) – NothingBox Aug 09 '20 at 05:41