如何将Java String转换为JSON对象

Nis*_*hit 7 java json org.json

之前已经提出过这个问题,但是我无法从对这些问题的回答中找出我的代码中的错误.


我试图将java字符串转换为json对象.这是代码:

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);
Run Code Online (Sandbox Code Playgroud)

输出是:

{"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"}]}
---------------------------
{}
Run Code Online (Sandbox Code Playgroud)

所以,正如你所看到的,jsonstring正在获取数据,但jsonObj却没有.我正在使用org.json JAR.

APD*_*APD 18

您将JSONObject构造函数传递给StringBuilder类的实例.

这是使用JSONObject(Object)构造函数,而不是JSONObject(String)一个.

你的代码应该是:

JSONObject jsonObj = new JSONObject(jsonString.toString());
Run Code Online (Sandbox Code Playgroud)

  • 你是第一个指出这一点的人. (2认同)

Bro*_*oks 5

@Nishit,JSONObject 本身并不理解如何通过 StringBuilder 进行解析;相反,您似乎正在使用 JSONObject(java.lang.Object bean) 构造函数来创建 JSONObject,但是将其传递给 StringBuilder。

有关该特定构造函数的更多信息,请参阅此链接。

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

当构造函数调用 java.lang.Object 类时,它很可能实际上是在告诉您,您需要创建自己的类(因为所有类最终都会扩展 java.lang.Object)并且它将与该类进行交互以特定的方式,尽管通常它会调用一个接口(因此得名),或者它可以“抽象地”接受任何类和接口,例如在其上调用 .toString() 。最重要的是,您通常不能只是通过任何课程并期望它能够发挥作用。

无论如何,这个特定的构造函数是这样解​​释的:

使用 bean getter 从对象构造 JSONObject。它反映了对象的所有公共方法。对于每个不带参数且名称以“get”或“is”开头并后跟大写字母的方法,将调用该方法,并将 getter 方法返回的键和值放入新的 JSONObject 中。键是通过删除“get”或“is”前缀而形成的。如果第二个剩余字符不是大写,则第一个字符将转换为小写。例如,如果一个对象有一个名为“getName”的方法,并且调用 object.getName() 的结果是“Larry Fine”,则 JSONObject 将包含“name”:“Larry Fine”。

所以,这意味着它期望您创建自己的类来实现 get 或 is 方法(即

public String getName() {...}
Run Code Online (Sandbox Code Playgroud)

或者

public boolean isValid() {...}
Run Code Online (Sandbox Code Playgroud)

因此,为了解决您的问题,如果您确实想要更高级别的控制并想要进行一些操作(例如修改某些值等)但仍然使用 StringBuilder 动态生成代码,您可以创建一个扩展 StringBuilder 的类类,以便您可以使用追加功能,但实现 get/is 方法以允许 JSONObject 从中提取数据,但这可能不是您想要/需要的,并且根据 JSON,您可能会花费大量时间以及创建私有字段和 get/is 方法的精力(或使用 IDE 为您完成),或者如果您不一定知道 JSON 字符串的细分,那么这一切可能都是徒劳的。

因此,您可以非常简单地调用toString()StringBuilder,它将提供 StringBuilder 实例的字符串表示形式并将其传递给 JSONObject 构造函数,如下所示:

...
StringBuilder jsonString = new StringBuilder();
while((readAPIResponse = br.readLine()) != null){
    jsonString.append(readAPIResponse);
}
JSONObject jsonObj = new JSONObject(jsonString.toString());
...
Run Code Online (Sandbox Code Playgroud)