如何将 Java 字符串转换为 JSON 对象

2022-09-02 20:22:46

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


我正在尝试将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);

输出为:

{"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"}]}
---------------------------
{}

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


答案 1

您正在将类的实例传递到构造函数中。JSONObjectStringBuilder

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

您的代码应该是:

JSONObject jsonObj = new JSONObject(jsonString.toString());

答案 2

@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 or is方法(即

public String getName() {...}

public boolean isValid() {...}

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

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

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