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

How to convert Java String to JSON Object

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


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

您传递给构造函数 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);

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

您正在向 JSONObject 构造函数传递一个 StringBuilder class.

的实例

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

您的代码应该是:

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

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

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

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

当构造函数调用 java.lang.Object class 时,很可能它实际上是在告诉您需要创建自己的 class(因为所有 类 最终扩展 java.lang.Object) 并且它将以特定方式与那个 class 接口,尽管通常它会调用一个接口(因此得名)或者它可以接受任何 class并与之交互 "abstractly" 例如在其上调用 .toString() 。最重要的是,您通常不能只传递它 any class 并期望它起作用。

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

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".

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

public String getName() {...}

public boolean isValid() {...}

所以,为了解决你的问题,如果你真的想要更高级别的控制并想做一些操作(例如修改一些值等)但仍然使用 StringBuilder 动态生成代码,你可以创建一个class 扩展了 StringBuilder class 以便您可以使用附加功能,但实现 get/is 方法以允许 JSONObject 从中提取数据,但这是可能不是你 want/need 并且取决于 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());
...

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