How to convert Java String to JSON Object
Asked Answered
S

6

20

This question has been asked earlier, but I am unable to figure out the error in my code from the responses to those questions.


I am trying to convert a java string into json object. Here is the code:

import org.json.JSONObject;
//Other lines of code
URL seatURL = new URL("http://freemusicarchive.org/api/get/genres.json?api_key=60BLHNQCAOUFPIBZ&limit=2");
//Return the JSON Response from the API
BufferedReader br = new BufferedReader(new InputStreamReader(seatURL.openStream(),Charset.forName("UTF-8")));
String readAPIResponse = " ";
StringBuilder jsonString = new StringBuilder();
while((readAPIResponse = br.readLine()) != null){
    jsonString.append(readAPIResponse);
}
JSONObject jsonObj = new JSONObject(jsonString);
System.out.println(jsonString);
System.out.println("---------------------------");
System.out.println(jsonObj);

The output is:

{"title":"Free Music Archive - Genres","message":"","errors":[],"total":"163","total_pages":82,"page":1,"limit":"2","dataset":[{"genre_id":"1","genre_parent_id":"38","genre_title":"Avant-Garde","genre_handle":"Avant-Garde","genre_color":"#006666"},{"genre_id":"2","genre_parent_id":null,"genre_title":"International","genre_handle":"International","genre_color":"#CC3300"}]}
---------------------------
{}

So, as you can see, the jsonstring is getting the data, but the jsonObj does not. I am using org.json JAR.

Steapsin answered 21/3, 2015 at 12:42 Comment(4)
Do you have a class that represents the raw JSON string? If so, what is its names?Ferreous
See this #5246340Canopy
@Ferreous : The string was created dynamically from the URL. I am not sure, if there is any other class that represents it, other than plain String class.Steapsin
@Canopy : When I create JSON Object as shown in the link you mentioned, it works. However, my data for the object comes dynamically, and when I try to create the JSONObject dynamically, it fails.Steapsin
L
36

You are passing into the JSONObject constructor an instance of a StringBuilder class.

This is using the JSONObject(Object) constructor, not the JSONObject(String) one.

Your code should be:

JSONObject jsonObj = new JSONObject(jsonString.toString());
Lezlie answered 21/3, 2015 at 13:16 Comment(4)
@user0815: The second one. See my answer with update. :)Ammoniacal
@MyGod You copied from this answer.Mockheroic
@Joiner: Lol..Indeed ? See timing.. :)Ammoniacal
@Joiner: Oops ! I haven't seen anything. I am blind.Ammoniacal
V
5

@Nishit, JSONObject does not natively understand how to parse through a StringBuilder; instead you appear to be using the JSONObject(java.lang.Object bean) constructor to create the JSONObject, however passing it a StringBuilder.

See this link for more information on that particular constructor.

http://www.json.org/javadoc/org/json/JSONObject.html#JSONObject%28java.lang.Object%29

When a constructor calls for a java.lang.Object class, more than likely it's really telling you that you're expected to create your own class (since all Classes ultimately extend java.lang.Object) and that it will interface with that class in a specific way, albeit normally it will call for an interface instead (hence the name) OR it can accept any class and interface with it "abstractly" such as calling .toString() on it. Bottom line, you typically can't just pass it any class and expect it to work.

At any rate, this particular constructor is explained as such:

Construct a JSONObject from an Object using bean getters. It reflects on all of the public methods of the object. For each of the methods with no parameters and a name starting with "get" or "is" followed by an uppercase letter, the method is invoked, and a key and the value returned from the getter method are put into the new JSONObject. The key is formed by removing the "get" or "is" prefix. If the second remaining character is not upper case, then the first character is converted to lower case. For example, if an object has a method named "getName", and if the result of calling object.getName() is "Larry Fine", then the JSONObject will contain "name": "Larry Fine".

So, what this means is that it's expecting you to create your own class that implements get or is methods (i.e.

public String getName() {...}

or

public boolean isValid() {...}

So, to solve your problem, if you really want that higher level of control and want to do some manipulation (e.g. modify some values, etc.) but still use StringBuilder to dynamically generate the code, you can create a class that extends the StringBuilder class so that you can use the append feature, but implement get/is methods to allow JSONObject to pull the data out of it, however this is likely not what you want/need and depending on the JSON, you might spend a lot of time and energy creating the private fields and get/is methods (or use an IDE to do it for you) or it might be all for naught if you don't necessarily know the breakdown of the JSON string.

So, you can very simply call toString() on the StringBuilder which will provide a String representation of the StringBuilder instance and passing that to the JSONObject constructor, such as below:

...
StringBuilder jsonString = new StringBuilder();
while((readAPIResponse = br.readLine()) != null){
    jsonString.append(readAPIResponse);
}
JSONObject jsonObj = new JSONObject(jsonString.toString());
...
Vowell answered 21/3, 2015 at 13:56 Comment(1)
The detailed answer like this, always help the naive people like us to understand what exactly is going on behind the curtain. Thanks for your time, sir.Promotion
L
2

Converting the String to JsonNode using ObjectMapper object :

ObjectMapper mapper = new ObjectMapper();

// For text string
JsonNode = mapper.readValue(mapper.writeValueAsString("Text-string"), JsonNode.class)

// For Array String
JsonNode = mapper.readValue("[\"Text-Array\"]"), JsonNode.class)

// For Json String 
String json = "{\"id\" : \"1\"}";
ObjectMapper mapper = new ObjectMapper();
JsonFactory factory = mapper.getFactory();
JsonParser jsonParser = factory.createParser(json);
JsonNode node = mapper.readTree(jsonParser);
Liturgist answered 28/3, 2017 at 13:23 Comment(0)
P
0
 ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> dataMap = objectMapper.readValue(decryptValue, Map.class);

        // Accessing dynamic keys
        for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            System.out.println("Key: " + key + ", Value: " + value);
        }
Paradies answered 21/4 at 8:2 Comment(0)
I
-1

The string that you pass to the constructor JSONObject has to be escaped with quote():

public static java.lang.String quote(java.lang.String string)

Your code would now be:

JSONObject jsonObj = new JSONObject.quote(jsonString.toString());
System.out.println(jsonString);
System.out.println("---------------------------");
System.out.println(jsonObj);
Inland answered 21/3, 2015 at 12:58 Comment(4)
quote() produces a String correctly formatted for insertion in a JSON text. Read doc here: json.org/javadoc/org/json/…Inland
@Joiner: This is another way to send jsonString.Ammoniacal
Then change quote() to JSONObject.quote(String) and link the JavaDoc.Mockheroic
@Joiner: Indeed, oops.Inland
A
-1

Your json -

{
    "title":"Free Music Archive - Genres",
    "message":"",
    "errors":[
    ],
    "total":"163",
    "total_pages":82,
    "page":1,
    "limit":"2",
    "dataset":[
    {
    "genre_id":"1",
    "genre_parent_id":"38",
    "genre_title":"Avant-Garde",
    "genre_handle":"Avant-Garde",
    "genre_color":"#006666"
    },
    {
    "genre_id":"2",
    "genre_parent_id":null,
    "genre_title":"International",
    "genre_handle":"International",
    "genre_color":"#CC3300"
    }
    ]
    }

Using the JSON library from json.org -

JSONObject o = new JSONObject(jsonString);

NOTE:

The following information will be helpful to you - json.org.

UPDATE:

import org.json.JSONObject;
 //Other lines of code
URL seatURL = new URL("http://freemusicarchive.org/
 api/get/genres.json?api_key=60BLHNQCAOUFPIBZ&limit=2");
 //Return the JSON Response from the API
 BufferedReader br = new BufferedReader(new         
 InputStreamReader(seatURL.openStream(),
 Charset.forName("UTF-8")));
 String readAPIResponse = " ";
 StringBuilder jsonString = new StringBuilder();
 while((readAPIResponse = br.readLine()) != null){
   jsonString.append(readAPIResponse);
 }
 JSONObject jsonObj = new JSONObject(jsonString.toString());
 System.out.println(jsonString);
 System.out.println("---------------------------");
 System.out.println(jsonObj);
Ammoniacal answered 21/3, 2015 at 13:4 Comment(2)
Maybe, I am really stupid, but I still cannot see the difference between what I have done and what you are suggesting. Could you please elaborate so that I can understand. ThanksSteapsin
You should delete this answer.Mockheroic

© 2022 - 2024 — McMap. All rights reserved.