在 Java 中解析 JSON 字符串

Posted

技术标签:

【中文标题】在 Java 中解析 JSON 字符串【英文标题】:Parsing JSON string in Java 【发布时间】:2012-08-06 04:14:55 【问题描述】:

我正在尝试在 java 中解析 JSON 字符串以分别打印单个值。但是在运行程序时出现以下错误-

Exception in thread "main" java.lang.RuntimeException: Stub!
       at org.json.JSONObject.<init>(JSONObject.java:7)
       at ShowActivity.main(ShowActivity.java:29)

我的班级看起来像-

import org.json.JSONException;
import org.json.JSONObject;

public class ShowActivity 
   private final static String  jString = "" 
   + "    \"geodata\": [" 
   + "        " 
   + "                \"id\": \"1\"," 
   + "                \"name\": \"Julie Sherman\","                  
   + "                \"gender\" : \"female\"," 
   + "                \"latitude\" : \"37.33774833333334\"," 
   + "                \"longitude\" : \"-121.88670166666667\""            
   + "                " 
   + "        ," 
   + "        " 
   + "                \"id\": \"2\"," 
   + "                \"name\": \"Johnny Depp\","          
   + "                \"gender\" : \"male\"," 
   + "                \"latitude\" : \"37.336453\"," 
   + "                \"longitude\" : \"-121.884985\""            
   + "                " 
   + "        " 
   + "    ]" 
   + ""; 
   private static JSONObject jObject = null;

   public static void main(String[] args) throws JSONException 
       jObject = new JSONObject(jString);
       JSONObject geoObject = jObject.getJSONObject("geodata");

       String geoId = geoObject.getString("id");
           System.out.println(geoId);

       String name = geoObject.getString("name");
       System.out.println(name);

       String gender=geoObject.getString("gender");
       System.out.println(gender);

       String lat=geoObject.getString("latitude");
       System.out.println(lat);

       String longit =geoObject.getString("longitude");
       System.out.println(longit);                   
   

让我知道我缺少什么,或者每次运行应用程序时都会出现该错误的原因。任何 cmets 将不胜感激。

【问题讨论】:

android.jar 仅包含要编译的存根。要运行,您需要完整的库。 是的,我在我的项目中导入了android.jar。你能告诉我从哪里可以下载完整的库吗? 【参考方案1】:

见我的comment。 您需要在运行时包含完整的org.json library,android.jar 仅包含要编译的存根。

此外,您必须删除 JSON 数据中 longitude 之后的两个额外 实例。

   private final static String JSON_DATA =
     "" 
   + "  \"geodata\": [" 
   + "    " 
   + "      \"id\": \"1\"," 
   + "      \"name\": \"Julie Sherman\","                  
   + "      \"gender\" : \"female\"," 
   + "      \"latitude\" : \"37.33774833333334\"," 
   + "      \"longitude\" : \"-121.88670166666667\""
   + "    ," 
   + "    " 
   + "      \"id\": \"2\"," 
   + "      \"name\": \"Johnny Depp\","          
   + "      \"gender\" : \"male\"," 
   + "      \"latitude\" : \"37.336453\"," 
   + "      \"longitude\" : \"-121.884985\""
   + "    " 
   + "  ]" 
   + ""; 

除此之外,geodata 实际上不是JSONObject,而是JSONArray

这里是完整的工作和测试的更正代码:

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class ShowActivity 


  private final static String JSON_DATA =
     "" 
   + "  \"geodata\": [" 
   + "    " 
   + "      \"id\": \"1\"," 
   + "      \"name\": \"Julie Sherman\","                  
   + "      \"gender\" : \"female\"," 
   + "      \"latitude\" : \"37.33774833333334\"," 
   + "      \"longitude\" : \"-121.88670166666667\""
   + "    ," 
   + "    " 
   + "      \"id\": \"2\"," 
   + "      \"name\": \"Johnny Depp\","          
   + "      \"gender\" : \"male\"," 
   + "      \"latitude\" : \"37.336453\"," 
   + "      \"longitude\" : \"-121.884985\""
   + "    " 
   + "  ]" 
   + ""; 

  public static void main(final String[] argv) throws JSONException 
    final JSONObject obj = new JSONObject(JSON_DATA);
    final JSONArray geodata = obj.getJSONArray("geodata");
    final int n = geodata.length();
    for (int i = 0; i < n; ++i) 
      final JSONObject person = geodata.getJSONObject(i);
      System.out.println(person.getInt("id"));
      System.out.println(person.getString("name"));
      System.out.println(person.getString("gender"));
      System.out.println(person.getDouble("latitude"));
      System.out.println(person.getDouble("longitude"));
    
  

这是输出:

C:\dev\scrap>java -cp json.jar;. ShowActivity
1
Julie Sherman
female
37.33774833333334
-121.88670166666667
2
Johnny Depp
male
37.336453
-121.884985

【讨论】:

谢谢veer。我打开了那个链接,但我找不到要下载的 jar 文件。你能指出我可以下载它的确切位置吗? @Nevzz03 试试here。 我按照你的建议做了。我也下载了jar,也导入了我们的项目。当我运行我的项目时,我遇到了异常 - Exception in thread "main" org.json.JSONException: JSONObject["geodata"] is not a JSONObject. at org.json.JSONObject.getJSONObject(JSONObject.java:596) at com.niharika.testing.JsonTest.main(JsonTest.java:31) 任何想法都将不胜感激。 @Nevzz03 我现在已经发布了完整的工作代码。让我知道你的效果如何。 org.json 的链接已失效。但是,该示例也适用于 JSON-Java。根据引用的包,我只需将文件移动到新创建的文件夹org/json/【参考方案2】:

要将您的 JSON 字符串转换为 hashmap,您可以使用这个:

HashMap<String, Object> hashMap = new HashMap<>(Utility.jsonToMap(response)) ;

使用这个类 :)(处理偶数列表、嵌套列表和 json)

public class Utility 

    public static Map<String, Object> jsonToMap(Object json) throws JSONException 

        if(json instanceof JSONObject)
            return _jsonToMap_((JSONObject)json) ;

        else if (json instanceof String)
        
            JSONObject jsonObject = new JSONObject((String)json) ;
            return _jsonToMap_(jsonObject) ;
        
        return null ;
    


   private static Map<String, Object> _jsonToMap_(JSONObject json) throws JSONException 
        Map<String, Object> retMap = new HashMap<String, Object>();

        if(json != JSONObject.NULL) 
            retMap = toMap(json);
        
        return retMap;
    


    private static Map<String, Object> toMap(JSONObject object) throws JSONException 
        Map<String, Object> map = new HashMap<String, Object>();

        Iterator<String> keysItr = object.keys();
        while(keysItr.hasNext()) 
            String key = keysItr.next();
            Object value = object.get(key);

            if(value instanceof JSONArray) 
                value = toList((JSONArray) value);
            

            else if(value instanceof JSONObject) 
                value = toMap((JSONObject) value);
            
            map.put(key, value);
        
        return map;
    


    public static List<Object> toList(JSONArray array) throws JSONException 
        List<Object> list = new ArrayList<Object>();
        for(int i = 0; i < array.length(); i++) 
            Object value = array.get(i);
            if(value instanceof JSONArray) 
                value = toList((JSONArray) value);
            

            else if(value instanceof JSONObject) 
                value = toMap((JSONObject) value);
            
            list.add(value);
        
        return list;
    


【讨论】:

【参考方案3】:

看起来你的两个对象(在数组内),在“经度”之后都有一个额外的右括号。

【讨论】:

【参考方案4】:

首先在每个array object 之后有一个额外的

其次,“地理数据”是JSONArray。因此,您必须使用JSONArray geoObject = jObject.getJSONArray("geodata"); 而不是JSONObject geoObject = jObject.getJSONObject("geodata");

获得JSONArray 后,您可以使用geoObject.get(&lt;index&gt;) 获取JSONArray 中的每个条目。

我正在使用org.codehaus.jettison.json

【讨论】:

【参考方案5】:

这是一个对象的示例,对于您的情况,您必须使用 JSONArray。

public static final String JSON_STRING="\"employee\":\"name\":\"Sachin\",\"salary\":56000";  
try  
   JSONObject emp=(new JSONObject(JSON_STRING)).getJSONObject("employee");  
   String empname=emp.getString("name");  
   int empsalary=emp.getInt("salary");  

   String str="Employee Name:"+empname+"\n"+"Employee Salary:"+empsalary;  
   textView1.setText(str);  

catch (Exception e) e.printStackTrace();  
   //Do when JSON has problem.

我没有时间,但试图给出一个想法。如果你还做不到,那我来帮忙。

【讨论】:

【参考方案6】:

每个对象中都有一个额外的“”, 你可以这样写 json 字符串:

public class ShowActivity    
    private final static String  jString = "" 
    + "    \"geodata\": [" 
    + "        " 
    + "                \"id\": \"1\"," 
    + "                \"name\": \"Julie Sherman\","                  
    + "                \"gender\" : \"female\"," 
    + "                \"latitude\" : \"37.33774833333334\"," 
    + "                \"longitude\" : \"-121.88670166666667\""            
    + "                " 
    + "        ," 
    + "        " 
    + "                \"id\": \"2\"," 
    + "                \"name\": \"Johnny Depp\","          
    + "                \"gender\" : \"male\"," 
    + "                \"latitude\" : \"37.336453\"," 
    + "                \"longitude\" : \"-121.884985\""            
    + "                " 
    + "        " 
    + "    ]" 
    + ""; 

【讨论】:

@Nevzz03 你可以使用linkflexjson java lib来创建你的json对象。【参考方案7】:

我们将使用 java 对象打印 json 的值。我们可以使用 Gson 库将 json 字符串解析为 java 对象。我们有一个像

这样的json字符串
   String json = ""id":1,"name" : "json" "

现在我们将 json 字符串解析为 java 对象,所以首先我们创建带有文件名 id 和名称的 java pojo

public class Student 
private int id;
private String  name;
     //getter 
    //setter
 

我们将使用 Gson 从 json 字符串创建学生对象

 Student stu = gson.fromJson(json, Student.class);

现在您可以使用 getter 打印任何 json 字段的值

     System.out.println(" id ="+ stu.getId() +" name ="+ stu.getName());

参考:How to convert JSON to / from Java Object Gson Example

【讨论】:

【参考方案8】:

如果我错了,请纠正我,但 json 只是由“:”分隔的文本,所以只需使用

String line = ""; //stores the text to parse.

StringTokenizer st = new StringTokenizer(line, ":");
String input1 = st.nextToken();

继续使用 st.nextToken() 直到数据用完。确保使用“st.hasNextToken()”,以免出现空异常。

【讨论】:

OP 正在寻找一种以最有效的方式解析 json 字符串的方法

以上是关于在 Java 中解析 JSON 字符串的主要内容,如果未能解决你的问题,请参考以下文章

java 解析json字符串格式 []

如何在PHP中解析json

java 解析json字符串

JAVA字符串用json来解析

JAVA字符串用json来解析

ios 在json解析过程中浮点型字符串出现精度丢失问题