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

20
这个问题之前已经被问过了,但是通过那些问题的回答我无法找到代码中的错误。
我正在尝试将一个Java字符串转换为JSON对象。 以下是代码:

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);

输出结果为:

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

所以,你可以看到,json字符串正在获取数据,但是jsonObj则没有。我使用的是org.json JAR。


你有一个代表原始JSON字符串的类吗?如果有,它的名称是什么? - Bohemian
请查看此链接:https://dev59.com/5W435IYBdhLWcg3wuiqz,了解如何在Java中将字符串转换为JSONObject。 - Gunaseelan
@Bohemian:该字符串是从URL动态创建的。我不确定是否有其他代表它的类,除了普通的String类。 - Nishit
@Gunaseelan :当我按照你提到的链接创建JSON对象时,它可以工作。但是,我的对象数据是动态获取的,当我尝试动态创建JSONObject时,它失败了。 - Nishit
5个回答

35

你正在将一个StringBuilder类的实例传递给JSONObject构造函数。

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

你的代码应该是:

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

@user0815:第二个。请看我的回答和更新。 :) - My God
1
@MyGod 你从这个答案里抄袭了。 - spongebob
@Joiner:哈哈,确实吗?看看时间... :) - My God
@Joiner:糟糕!我什么也没看到。我是盲人。 - My God

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 getters 构造一个 JSONObject。它会反射该对象的所有公共方法。对于没有参数并以“get”或“is”开头后跟大写字母的名称的每个方法,该方法将被调用,并且键和从 getter 方法返回的值将放入新的 JSONObject 中。键由删除“get”或“is”前缀形成。如果第二个剩余字符不是大写字母,则将第一个字符转换为小写字母。例如,如果一个对象有一个名为“getName”的方法,并且调用 object.getName() 的结果为“Larry Fine”,则 JSONObject 将包含“name”:“Larry Fine”。
因此,这意味着它期望你创建自己的类来实现 get 或 is 方法(即
public String getName() {...}

或者

public boolean isValid() {...}

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

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

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

这样详细的回答总是能帮助像我们这样的新手理解幕后到底发生了什么。感谢您的时间,先生。 - gaurav kumar

2
使用ObjectMapper对象将字符串转换为JsonNode:
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);

-1

你传递给构造函数 JSONObject 的字符串必须使用 quote() 进行转义:

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

你的代码现在应该是:

JSONObject jsonObj = new JSONObject.quote(jsonString.toString());
System.out.println(jsonString);
System.out.println("---------------------------");
System.out.println(jsonObj);

quote()方法生成一个适合插入JSON文本的格式化字符串。在这里阅读文档:http://www.json.org/javadoc/org/json/JSONObject.html#quote(java.lang.String) - Ola
@Joiner:这是另一种发送 jsonString 的方式。 - My God
然后将 quote() 更改为 JSONObject.quote(String) 并链接 JavaDoc。 - spongebob
@Joiner:确实,糟糕。 - Ola

-1

你的 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"
    }
    ]
    }

使用来自 json.org 的 JSON 库 -

JSONObject o = new JSONObject(jsonString);

注意:

以下信息对您有所帮助 - json.org

更新:

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);

3
或许我真的很蠢,但我仍然看不出我所做的和你所建议的有何区别。您能否详细说明,以便我能理解。谢谢。 - Nishit
2
你应该删除这个答案。 - spongebob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接