【问题标题】:How to convert Java String to JSON Object如何将 Java 字符串转换为 JSON 对象
【发布时间】:2015-05-24 19:48:22
【问题描述】:

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


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

【问题讨论】:

  • 你有代表原始 JSON 字符串的类吗?如果有,它的名字是什么?
  • @Bohemian :字符串是从 URL 动态创建的。我不确定,除了普通的 String 类之外,是否还有任何其他类可以代表它。
  • @Gunaseelan :当我创建 JSON 对象时,如您提到的链接所示,它可以工作。但是,我的对象数据是动态来的,当我尝试动态创建 JSONObject 时,它会失败。

标签: java json org.json


【解决方案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 文本。在此处阅读文档:json.org/javadoc/org/json/…
  • @Joiner:这是发送jsonString的另一种方式。
  • 然后将quote()更改为JSONObject.quote(String)并链接JavaDoc。
  • @Joiner:确实,哎呀。
【解决方案2】:

你的 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】:

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

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

你的代码应该是:

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

【讨论】:

  • @user0815:第二个。请参阅我的更新答案。 :)
  • @MyGod 您从 this 答案中复制。
  • @Joiner:大声笑..真的吗?看时间.. :)
  • @Joiner:哎呀!我什么都没看到。我是盲人。
【解决方案4】:

@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 从 Object 构造 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 类,以便您可以使用附加功能,但实现 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());
...

【讨论】:

  • 这样的详细解答,总能帮助像我们这种天真的人搞清楚幕后到底是怎么回事。谢谢您的宝贵时间,先生。
【解决方案5】:

使用 ObjectMapper 对象将 String 转换为 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);

【讨论】:

    猜你喜欢
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 2012-05-05
    相关资源
    最近更新 更多